线性dp
P1280 尼克的任务 线性dp
其实看到这道题第一眼看成了贪心
其实是个很奇怪的线性dp
dp[i]代表在i到n时间内的最长休息时间
先放状态转移方程这里的list[num].t是指第num个工作的起始时间
由题意可知 只有空闲时间有任务开始 才会去做
所以我们枚举每个这段时间的任务 看那个能够获得最长的休息时间但是要注意 这里循环要倒着跑 因为dp[i]=dp[i+1]+1; 如果顺着跑 在跑到dp[i]时 很显然dp[i+1]还没有转移过知道了思路 放代码
dp[i] = max(dp[i],dp[i+list[num].t]);//如果此刻有任务 dp[i] = dp[i+1]+1;//如果此刻没任务
#define rep(i,a,b) for(int i=a;i<=b;i++) #include <stdio.h> #include <iostream> #include <algorithm> using namespace std; const int e = (int)1e5+5; struct node { int p; int t; }list[e]; bool cmp(node a,node b){ return a.p>b.p; } int num=1; int dp[e],sum[e]; int n,k; int main(int argc, char const *argv[]) { cin >> n >> k; rep(i,1,k){ cin >> list[i].p >> list[i].t; sum[list[i].p]++; } sort(list+1,list+1+k,cmp); for(int i = n;i >= 1;i--){ if(!sum[i]){ dp[i] = dp[i+1]+1; } else for(int j = 1;j <= sum[i]; j++){ dp[i] = max(dp[i],dp[i+list[num].t]); num++; } } printf("%d\n",dp[1]); return 0; }
人十我百 人百我万