线性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;
}

  

posted @ 2019-04-15 18:37  Rain_day  阅读(205)  评论(0编辑  收藏  举报