P1280 尼克的任务

传送门

思路:

  动态规划:设 f [ i ] 表示第 i 个任务开始时,可获得的最大空闲时间。

  转移方程:

    ① 若此时无任务:f [ i ] = max( f [ i ] , f [ i-1 ]+1 )。

    ② 若此时有任务:f [ i+wj-1 ] = max( f [  i+wj-1 ] , f [ i-1 ] )。

  注:有任务时,用 j 枚举开始的时间为 i 的任务,提前更新掉第 j 个任务结束的时间 i+wj-1 的 f [ i+wj-1 ]。

标程:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define maxn 10001
#define INF -0x3f
typedef long long LL;
LL n,k;
LL f[maxn];
struct hh
{
    LL l,w;
}t[maxn];
inline LL read()
{
    LL xs=0,kr=1;char ls;
    ls=getchar();
    while(!isdigit(ls))
    {
        if(!(ls^45))
            kr=-1;
        ls=getchar();
    }
    while(isdigit(ls))
    {
        xs=(xs<<1)+(xs<<3)+(ls^48);
        ls=getchar();
    }
    return xs*kr;
}
int main()
{
    memset(f,INF,sizeof(f));
    n=read();k=read();
    for(LL i=1;i<=k;i++)
        t[i].l=read(),t[i].w=read();
    LL j=0;f[0]=0;
    for(LL i=1;i<=n;i++)
    {
        if(t[j+1].l!=i) f[i]=max(f[i],f[i-1]+1);
        while(j<k&&t[j+1].l==i)
        {
            j++;//j不断增加,即枚举任务。 
            f[i+t[j].w-1]=max(f[i+t[j].w-1],f[i-1]);
        }
    }
    printf("%lld\n",f[n]);
return 0;
}

 

posted @ 2018-10-15 12:04  落笔映惆怅丶  阅读(169)  评论(0编辑  收藏  举报