【问题标题】:Solving SUPW from ZCO 2014从 ZCO 2014 解决 SUPW
【发布时间】:2017-03-18 01:35:05
【问题描述】:

在为即将到来的 ZCO 练习时,我遇到了 this 问题,这里是其中的摘录,

在 ICO School,所有学生都必须定期参加 SUPW。 每天都有不同的 SUPW 活动,每个活动都有自己的 自己的持续时间。下一学期的SUPW时间表已经公布, 包括有关每个人所用分钟数的信息 活动。

Nikhil 已被指定为 SUPW 协调员。他的任务是分配 SUPW 对学生的职责,包括他自己。学校规定说 没有任何学生可以连续三天没有任何 SUPW 职责。

Nikhil 想为自己找到一份 SUPW 职责的任务, 最大限度地减少他在 SUPW 上花费的总分钟数。

考虑 DP 解决方案,我花了一天的时间将其添加到接下来的 3 天,并取它们的最小值来获得第二天 Nikhil 应该执行任务的时间,但是我在比较的事情上几乎搞砸了,这就是我已经努力了,

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

int calcmintime(std::vector<std::vector<int> >matrix,int n,int j,std::vector<int>duty){
    int time1 = matrix[0][j];
    int time2 = matrix[1][j];
    int time3 = matrix[2][j];
    if(time1+time2+time3 == 0){
        return 0;
    }
    if(time1 < time2 && time1 < time3 ){
        j = j + 1;
        return (duty[j]+calcmintime(matrix,n,j,duty));
    }
    if(time2 < time3 && time2 < time1 ){
        j = j + 2;
        return (duty[j]+calcmintime(matrix,n,j,duty));
    }
    if(time3 < time2 && time3 < time1 ){
        j = j + 3;
        return (duty[j]+calcmintime(matrix,n,j,duty));
    }
    if(time1 == time2 && time1 < time3){
        int a = j+1;
        int b = j+2;
        int forA = duty[j]+calcmintime(matrix,n,a,duty);
        int forB = duty[j]+calcmintime(matrix,n,b,duty);
        if(forA > forB){
            return forB;
        }else{
            return forA;
        }
    }
    if(time1 == time3 && time1 < time2){
        int a = j+1;
        int b = j+3;
        int forA = duty[j]+calcmintime(matrix,n,a,duty);
        int forB = duty[j]+calcmintime(matrix,n,b,duty);
        if(forA > forB){
            return forB;
        }else{
            return forA;
        }
    }
    if(time2 == time3 && time2 < time1){
        int a = j+3;
        int b = j+2;
        int forA = duty[j]+calcmintime(matrix,n,a,duty);
        int forB = duty[j]+calcmintime(matrix,n,b,duty);
        if(forA > forB){
            return forB;
        }else{
            return forA;
        }
    }
    if(time1 == time2 && time2 == time3){
        int a = j+1;
        int b = j+2;
        int c = j+3;
        int forA = duty[j]+calcmintime(matrix,n,a,duty);
        int forB = duty[j]+calcmintime(matrix,n,b,duty);
        int forC = duty[j]+calcmintime(matrix,n,c,duty);
        int result = forA;
        if(forB < result){
            result = forB;
        }
        if(forC < result){
            result = forC;
        }
        return result;
    }
}

int main(){
    int days;
    std::cin >> days;
    std::vector<int>dutyTime(days);
    //std::cout << "got it" << std::endl;
    for(int i=0;i<days;i++){
        std::cin >> dutyTime[i];
    }
    std::vector<std::vector<int> >timeMat(3,std::vector<int>(days,0));
    for(int i=0;i<3;i++){
        int j;
        for(j=0;j<days-1-i;j++){
            timeMat[i][j] = dutyTime[j] + dutyTime[j+1+i];
            //std::cout << timeMat[i][j] << ' ' << i << ' ' << j << ' ' << std::endl;
        }
        //std::cout << std::endl;
    }
    int mintime = INT_MAX;
    for(int i=0;i<3;i++){
        int newmin = dutyTime[i]+calcmintime(timeMat,days,i,dutyTime);
        if(newmin < mintime){
            mintime = newmin;
        }
    }
    std::cout << mintime << std::endl;
    return 0;
}

好的,这段代码给出了 12 次中的 2 次正确答案,所以我走的是正确的道路,但应该错过了一些可能会扰乱我的程序的情况。 任何人都可以为这个问题提出更好的方法吗?

更新: 我尝试了另一种方法(尽管输入小于 4 会出现问题),但结果是一样的:

#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    int n;
    std::cin >> n;
    std::vector<int>dutyTime(n);
    for(int i=0;i<n;i++){
        std::cin >> dutyTime[i];
    }
    std::vector<int>bestTime(n);
    bestTime[0] = dutyTime[0] + std::min(dutyTime[1],std::min(dutyTime[2],dutyTime[3]));
    bestTime[1] = dutyTime[1] + std::min(dutyTime[2],std::min(dutyTime[3],dutyTime[4]));
    bestTime[2] = dutyTime[2] + std::min(dutyTime[3],std::min(dutyTime[4],dutyTime[5]));
    for(int i=3;i<n-3;i++){
        bestTime[i] = std::min(bestTime[i-3],std::min(bestTime[i-2],bestTime[i-1])) + std::min(dutyTime[i+1],std::min(dutyTime[i+2],dutyTime[i+3]));
    }
    std::cout << bestTime[n-4] << std::endl;
    return 0;
}

注意:对不起,因为它是为了竞争性编程,我还没有记录下来

【问题讨论】:

  • 嗯! Line 1: A single integer N, the number of days in the future for which SUPW data is available... 1 ≤ N ≤ 2×10^5那个ICO学校的东西:200'000days是> 500年。
  • 呵呵,还以为有人回答了我的问题……

标签: c++ algorithm multidimensional-array dynamic-programming


【解决方案1】:

我很快就解决了,代码也少了很多:)

代码如下:

#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    int n;
    std::cin >> n;
    std::vector<int>dutyTime(n);
    for(int i=0;i<n;i++){
        std::cin >> dutyTime[i];
    }
    std::vector<int>bestTime(n);
    bestTime[0] = dutyTime[0];
    bestTime[1] = dutyTime[1];
    bestTime[2] = dutyTime[2];
    for(int i=3;i<n;i++){
        bestTime[i] = dutyTime[i]+std::min(bestTime[i-1],std::min(bestTime[i-2],bestTime[i-3]));
    }

    std::cout << std::min(bestTime[n-1],std::min(bestTime[n-2],bestTime[n-3])) << std::endl;

    return 0;
}

说明:

前 3 天的最短时间只能是分配给当天的时间,接下来的几天我们可以简单地选择最后三天的最短时间,然后加上分配给当天的时间,tada最后,最后三天的最短时间是 Nikhil 可以在营地度过的最短时间。

【讨论】:

  • @FanilGandhi 你的任务有 8 个,所以如果我选择第 3 个和第 5 个,我仍然满足标准,并且可能的最低总数将是 2 而不是 3 , 0 0 1 0 0 1 0 0 -> 这就是八天的工作。
  • 是的,这是一个错字。我想在其中添加 9 1
  • 假设提供的值为 1 1 1 1 1 1 1 1 1。ans 为 3 但您的算法不起作用
  • 确定吗?请再次检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多