线性动态规划尼克的任务
Posted xwww666666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性动态规划尼克的任务相关的知识,希望对你有一定的参考价值。
额一道挺水的题,愣是做了几个小时
动态规划大致的思路还是找一个转移
换个词就是影响
我们可以明显看出本题的规则:
空暇时,一遇到任务必须挑一个接
求1-n时间内最大空暇时间
所以将任务排序是必要的,两个关键字
再来想象一下当我做到第a个任务时,我在st[i]-(st[i]+t[i]-1)时必然在工作
那么1-(st[i]+t[i]-1)的区间内,
是我上一个任务的f[j]和与j任务之间的时间空暇决定的
则现在的问题是,找出所以合法j任务,然后加上st[i]-st[j]-t[j]
合法的j任务应该满足什么要求呢
st[i]之前已经完成,但是又不能已经完成了太久
这个不能完成太久的条件,其实正着推最容易,
就是j+1任务往后数,最先开始的那个就是,
所以我们需要一个新数组,预处理这个最先开始
当然我其实不想要这个数组
所以我想每个当前任务点,去更新后面的任务点
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; int m,n; const int N=10003; struct node int st,ed;//这里是左闭合,右开 bool operator < (const node & o) const if(st!=o.st) return st<o.st; else return ed<o.ed; d[N]; int f[N]; int main() scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d",&d[i].st ,&d[i].ed ),d[i].ed +=d[i].st ; d[++n].st =m+1,d[n].ed =m+1; sort(d+1,d+n); memset(f,-1,sizeof(f)); int i=2; f[1]=d[1].st -1; while(i<n && d[i].st ==d[1].st ) f[i++]=f[1]; for(i=1;i<n;i++) if(f[i]==-1) continue; int nx=i+1; while(nx<n && d[nx].st <d[i].ed ) nx++; //printf("%d %d\n",d[i].st ,d[i].ed ); int dis=d[nx].st -d[i].ed ; for(int j=nx;j<=n && d[j].st ==d[nx].st ;j++) f[j]=max(f[i]+dis,f[j]); //,printf(" %d %d %d\n",d[j].st ,d[j].ed ,f[j]); //if(d[j].st ==9994) printf("%d %d %d\n",i,f[i],dis); printf("%d\n",f[n]); return 0;
//倒序做 //为什么? #include<cstdio> #include<cstdlib> #include<algorithm> #include<vector> using namespace std; int m,n; const int N=10003; vector <int> t[N]; int f[N]; int main() scanf("%d%d",&m,&n); int st,ed; for(int i=1;i<=n;i++) scanf("%d%d",&st ,&ed ),ed +=st ,t[st ].push_back(ed); for(int i=m;i;i--) int sz=t[i].size(); if(!sz) f[i]=f[i+1]+1; continue; for(int j=0;j<sz;j++) ed=t[i][j]; f[i]=max(f[i],f[ed ]); printf("%d\n",f[1]); return 0;
以上是关于线性动态规划尼克的任务的主要内容,如果未能解决你的问题,请参考以下文章