再来一道dp ~ 莫怪我蒟蒻啊……
其实我一开始是想 f [ i ] 表示 1 ~ i 的休息时间的最大值,但是发现一个问题:第 i 时刻的最大空闲时间和之后的任务是有关系的,所以我们只能从后往前扫一遍(数据范围显然是线性的)。
那么对于空闲时间,自然等于上一刻 + 1 ,而对于一个左端点,自然是和这段任务结束的下一刻的最大值。然而在一刻发生的任务可能有很多,所以需要记下来都算一遍。
下面是代码:
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> using namespace std; #define maxn 20000 int f[maxn],sum[maxn],now=1; struct node { int l,w; } a[maxn]; bool cmp(node x,node y) { return x.l>y.l; } int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1; i<=k; i++) { scanf("%d%d",&a[i].l,&a[i].w); sum[a[i].l]++; } sort(a+1,a+k+1,cmp); for(int i=n; i>=1; i--) { if(!sum[i]) f[i]=f[i+1]+1; else for(int j=1; j<=sum[i]; j++) f[i]=max(f[i],f[i+a[now++].w]); } printf("%d",f[1]); return 0; }