P1280 尼克的任务

  再来一道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;
}

 

posted @ 2019-01-30 19:42  paopo  阅读(145)  评论(0编辑  收藏  举报