尼克的任务(P1280)

来源:互联网 发布:星际争霸2战役兵种数据 编辑:程序博客网 时间:2024/04/30 19:46

题目链接:尼克的任务
这道题,有点难度,也不是太难,因为我都做出来了。
好,下面分析一下:
这道题,显然的动规,我们这样设计状态。
我们设d[i]为从第i分钟初开始到结束有多少空闲时间。
那么我们的转移方程也出来了:
如果第i分钟没有开始的任务,那么
d[i]=d[i+1]+1;
这很好理解,因为不需要做任务,那么空闲时间就是前一种状态的时间加上新增的1分钟。
如果有第i分钟开始的任务,那么:
d[i]=max{d[i+t[j]]},j为任务的标号
这应该好理解,因为如果有任务,那么尼克是需要做任务的,所以一定要选择一个任务来做。那么做任务的这段时间肯定没有空闲时间,所以直接跳到任务完成的时间状态。
下面给代码。
给代码之前,讲一下,我的这个代码是有前提的,就是任务的输入按时间是有序的,题目似乎没讲,但提交是能AC的。所以,如果真的考试,是需要先排一下序,然后就行了。这里就不加排序代码了。

#include<bits/stdc++.h>using namespace std;int n,k;int main(){    scanf("%d%d",&n,&k);    int begin[k],t[k],vis[n+1];//vis用来存储这个时间点有没有任务    memset(vis,0,sizeof(vis));    for(int i=0;i<k;i++){        scanf("%d%d",&begin[i],&t[i]);        vis[begin[i]]=1;             //1    }    int tail=k-1;                     //2    int d[n+2];    memset(d,-1,sizeof(d));    d[n+1]=0;                       //3    for(int i=n;i>=1;i--){        if(vis[i]==1){             //4            while(begin[tail]==i){             //7                d[i]=max(d[i],d[i+t[tail--]]);  //5            }        }else{            d[i]=d[i+1]+1;             //6        }    }    printf("%d",d[1]);    return 0;} 

今天讲7点(还是挺多的哈):
1处:读入开始时间,把对应时间点标为有任务。
2处:这是任务的序号,我们这里默认是有序的,所以可以用一个tail去处理任务序号。
3处:边界。
4处:如果有任务
5处:注意tail–,这里因为有序,所以序号后面的任务,一定已经执行过,所以不断推进就行。
6处:如果没任务,那么就直接加一。
7处:如果这个任务是这个时间开始的,那么就执行,注意我们加了一个循环,因为一个时间点有多个任务,所以我们需要不断执行。

原创粉丝点击