尼克的任务题解

大致题意:

在N个时间段中有M个任务,每个任务有一个开始时间和持续时间,当一个有任务的时间段尼克为空闲状态时,他必须进行当前的任务,如果有多个任务,他可以选择任意一个。求他能空闲的最大值。

N,M<=1e4

状态:

由于如果从前往后设置状态,那么会有后效性,所以我们只需从后往前设置即可,即f[i]表示i到N可以获得的最大空闲值。

那么如果当前时间段没有任务时,f[i]=f[i+1]+1;有任务时就是f[i]=max(f[i],f[a[i].start+a[i].last]).那么最终结果就是f[1].

代码如下:
 

#include<cstdio>
#include<algorithm>
using namespace std;

const int N=10010,M=10010;
struct time{
	int st,la;
}a[M];
int f[N],n,m;

int read() {
	int S=0,F=1;char C=getchar();
	for(;C<'0' || C>'9';C=getchar()) 
		if(C=='-') F=-1;
	for(;C>='0' && C<='9';C=getchar())
		S=(S<<3)+(S<<1)+C-48;
	return S*F;
}

bool cmp(time xx,time yy) {
	return xx.st>yy.st;
}

int main() {
	n=read(),m=read();
	for(int i=1;i<=m;i++) a[i].st=read(),a[i].la=read();
	sort(a+1,a+m+1,cmp); //因为需从大到小设置状态,所以需要从大到小排序.
	int now=1;
	for(int i=n;i;i--) 
		if(a[now].st!=i) 
			f[i]=f[i+1]+1;
		else
			for(;i==a[now].st;) 
			    f[i]=max(f[i],f[a[now].st+a[now].la]),now++;
	printf("%d\n",f[1]);
	return 0;
}

复杂度为O(n(+常数)).

猜你喜欢

转载自blog.csdn.net/chenkainan1023/article/details/81835359