【洛谷P1280】尼克的任务

题目大意:一个人在时间 [1,N] 内工作,现有 M 个任务,每个任务需要在一段固定的时间区间内完成,任务之间的时间可能有重叠。若当前时间有任务要开始,且人处于空闲状态,则一定要这个人来做,否则这个人忽略这个任务。求用以上原则进行工作的最长休息时间是多少。

题解:
若用 f[i] 表示前 i 分钟的最长休息时间的话,发现很难表示出 i 这个点有任务就一定要执行的情况,原因是这是对未来状态的考量。考虑重新设计状态,f[i] 表示从 i 到 N 的最大空闲时间是多少,发现若当前 i 时间有任务要执行,则可以用做完任务的时间转移到当前时间的最优解,就很舒服了。另外,可以用排序优化一下,时间复杂度为 \(O(N+M)\)

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;

int n,m,f[maxn];
struct node{int st,t;}e[maxn];

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d%d",&e[i].st,&e[i].t);
	sort(e+1,e+m+1,[](const node &x,const node &y){return x.st<y.st;});
	
	for(int i=n,j=m;i>=1;i--){
		while(j>=1&&e[j].st>i)--j;
		if(j>=1&&e[j].st==i){
			while(j>=1&&e[j].st==i)f[i]=max(f[i],f[i+e[j].t]),--j;
		}else{
			f[i]=f[i+1]+1;
		}
	}
	printf("%d\n",f[1]);
	
	return 0;
}
posted @ 2019-06-27 11:42  shellpicker  阅读(442)  评论(0编辑  收藏  举报