P1280 尼克的任务 /// DP(选择性地)

题目大意:

https://www.luogu.org/problemnew/show/P1280

 

题解 手推一遍思路更清晰

#include <bits/stdc++.h>
using namespace std;
struct NODE{ int x,y; }a[10005];
bool cmp(NODE& a,NODE& b) {
    return a.x>b.x;
}
int sum[10005],dp[10005];
/// sum[i]记录在i时间开始的事情的个数
/// dp[i]记录从i到末尾最多的空闲时间
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=0;i<k;i++) {
        int u,v; scanf("%d%d",&u,&v);
        a[i].x=u, a[i].y=v; sum[u]++;
    }
    sort(a,a+k,cmp); /// 按开始时间逆序排序
    int m=0;
    for(int i=n;i>0;i--) { /// 从末尾反过来扫一遍
        if(!sum[i]) dp[i]=dp[i+1]+1; 
        // 如果这个时间点没有事件开始 则空闲时间+1
        else /// 否则 判断做这几件事 能否使空闲时间更多
            while(sum[i]--) {
                if(dp[i+a[m].y]>dp[i]) // 若可以 则做这件事 得到更长的空闲时间
                    dp[i]=dp[i+a[m].y];
                m++;
            }
    }
    printf("%d\n",dp[1]);

    return 0;
}
View Code

 

posted @ 2018-07-18 07:42  _Jessie  阅读(225)  评论(0)    收藏  举报