P1280 尼克的任务(无后效性)

https://www.luogu.com.cn/problem/P1280

所谓无后效性原则,指的是这样一种性质:某阶段的状态一旦确定,则此后过程的演变不再受此前各状态及决策的影响。也就是说,“未来与过去无关”,当前的状态是此前历史的一个完整总结,此前的历史只能通过当前的状态去影响过程未来的演变。具体地说,如果一个问题被划分各个阶段之后,阶段k中的状态只能通过阶段k+1中的状态通过状态转移方程得来,与其他状态没有关系,特别是与未发生的状态没有关系,这就是无后效性。

对于尼克的任务这个题:第一时间想到设f[i]:1~i的最大空闲时间,但是,想了一下之后发现,第i时刻的最大空闲时间是和后面i+选择任务的持续时间的时刻有关系的,原因是这是对未来状态的考量,不符合动态规划的无后效性。

我们来试一下倒着搜,即设f[i]表示i~n的最大空闲时间,经尝试,发现是完全可行的,可以列出动态转移方程如下:

(本时刻无任务)f[i]=f[i+1]+1;//继承上一个时刻的最大空闲时间后+1

(本时刻有任务)f[i]=max(f[i],f[i+a[sum])//a[sum]表示在这个时刻的任务的持续时间,找出选择哪一个本时刻任务使空闲时间最大化

 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,k,s,t,f[10002];
 6 vector<int>v[10001];
 7 int main(){
 8     scanf("%d%d",&n,&k);
 9     while(k--){
10         scanf("%d%d",&s,&t);
11         v[s].push_back(t);//记录开始时间相同的任务,结束时间压到vector 
12     }
13     for(int i=n;i;--i){
14         if(v[i].size()>0)//有任务时 
15             for(int j=0;j<v[i].size();++j)//把当前时刻的任务数的状态枚举选最优 
16                 f[i]=max(f[i],f[i+v[i][j]]);
17         else f[i]=f[i+1]+1;//没有任务时, 当前状态结果为上一状态+1            
18     }
19     printf("%d",f[1]);
20 }
原文地址:https://www.cnblogs.com/tflsnoi/p/14801282.html