P1280 尼克的任务

中文题

 

想法:

首先状态的设定很容易想 

f[i] 代表第 i 时刻可获得的最大空暇时间

但是状态转移的时候我们发现 如果正向转移,f[i] 会受到后面选择的i以及它的持续时间的影响,所以不可以正向转移

那么我们考虑倒着转移

f[i] = f[i+1] + 1  (当前时刻无任务)

f[i] = max{f[i],f[i+p[i].ed]} (当前时刻有任务)

 

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f

const double eps = 1e-10;
const int maxn = 1e4 + 10;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct node {
    LL st,ed;
}p[maxn];

bool cmp (node a,node b) {
    return a.st > b.st;
}

LL f[maxn],vis[maxn];

int main() {
    //freopen("../in.txt","r",stdin);
    int n,k;
    scanf("%d%d",&n,&k);
    for (int i = 1;i <= k;i++) {
        scanf("%lld%lld",&p[i].st,&p[i].ed);
        vis[p[i].st]++;
    }
    sort(p+1,p+1+k,cmp);
    int cnt = 1;
    for (int i = n;i >= 1;i--) {
        if (!vis[i])
            f[i] = f[i+1] + 1;
        else {
            for (int j = 1;j <= vis[i];j++) {
                f[i] = max(f[i],f[i+p[cnt].ed]);
                cnt++;
            }
        }
    }
    printf("%lld\n",f[1]);
    return 0;
}

 

posted @ 2020-03-10 22:14  _Ackerman  阅读(214)  评论(0编辑  收藏  举报