P1156 垃圾陷阱 传送门

P1156 垃圾陷阱
传送门

思路:

  设 f [ i ][ j ] 表示,扔进去 i 个垃圾,垃圾高度为 j 时,奶牛的生命值。

  初始化 f 数组为 -1,因为当奶牛生命值为 0 时,奶牛还是可以操纵垃圾。f [ 0 ][ 0 ] = 10 为奶牛的初始生命值。

  转移如下:

  ① 当 f [ i ][ j ] < 0 时,说明这个状态奶牛已经死了,跳过。

  ② 当 f [ i ][ j ] = 0 时,奶牛处于濒死状态,还可以操作,必须吃掉垃圾。进而判断这个垃圾恢复的生命值是否能够支撑到下一个垃圾的投入,若不能,就跳过,否则就转移状态。

  ③ 当 f [ i ][ j ] > 0 时,判断奶牛不吃这个垃圾的生命值能否支撑到下一个垃圾的投入,能,就把垃圾堆起来。不能,就吃掉。吃掉后再判断能否转移,同 ② 。

伪代码:

struct hh
{
    LL tim,w,h;//tim垃圾投入的时间、w垃圾恢复的生命值、h垃圾的高度 
}t[maxn];
f[0][0]=10;
for(LL i=0;i<g;i++)//第一重循环,枚举投入的垃圾 
    for(LL j=0;j<=d;j++)//枚举高度 
    {
        if(f[i][j]<0) continue;//如果奶牛无法到达这个状态,跳过 
        if(j+t[i+1].h>=d&&f[i][j]>=t[i+1].tim-t[i].tim)//判断奶牛在不吃这个垃圾的状态下,能否跳出陷阱 
        {
            out(t[i+1].tim);return 0;
        }
        if(f[i][j]-t[i+1].tim+t[i].tim>=0)//同时判断、转移②,③两种情况 
        {
            f[i+1][j+t[i+1].h]=f[i][j]-t[i+1].tim+t[i].tim;
            f[i+1][j]=lck_max(f[i+1][j],f[i][j]-t[i+1].tim+t[i].tim+t[i+1].w);
        }
    }

标程:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define lck_max(a,b) ((a)>(b)?(a):(b))
#define lck_min(a,b) ((a)<(b)?(a):(b))
typedef long long LL;
#define maxn 1001
LL d,g,ans,las,f[maxn][maxn];
struct hh
{
    LL w,h,tim;
}t[maxn];
inline LL read()
{
    LL kr=1,xs=0;
    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;
}
inline void out(LL xs)
{
    if(!xs) {putchar(48); return;}
    if(xs<0) putchar('-'),xs=-xs;
    int kr[57],ls=0;
    while(xs) kr[++ls]=xs%10,xs/=10;
    while(ls) putchar(kr[ls]+48),ls--;
}
inline bool cmp(const hh&a,const hh&b)
{
    return a.tim<b.tim;
}
int main()
{
    freopen("ljxj.in","r",stdin);
    freopen("ljxj.out","w",stdout);
    d=read();g=read();
    for(LL i=1;i<=g;i++)
    {
        t[i].tim=read();t[i].w=read();t[i].h=read();
    }
    sort(t+1,t+g+1,cmp);
    memset(f,-1,sizeof(f));
    f[0][0]=10;
    for(LL i=0;i<g;i++)
        for(LL j=0;j<=d;j++)
        {
            if(f[i][j]<0) continue;
            if(j+t[i+1].h>=d&&f[i][j]>=t[i+1].tim-t[i].tim)
            {
                out(t[i+1].tim);return 0;
            }
            if(f[i][j]-t[i+1].tim+t[i].tim>=0)
            {
                f[i+1][j+t[i+1].h]=f[i][j]-t[i+1].tim+t[i].tim;
                f[i+1][j]=lck_max(f[i+1][j],f[i][j]-t[i+1].tim+t[i].tim+t[i+1].w);
            }
        }
    for(LL i=1;i<=g;i++)
    {
        if(t[i].tim-t[i-1].tim>f[0][0])
            break;
        ans+=t[i].tim-t[i-1].tim;
        f[0][0]-=t[i].tim-t[i-1].tim;
        f[0][0]+=t[i].w;
    }
    ans+=f[0][0];
    out(ans);
return 0;
}