洛谷【P1156】垃圾陷阱

也是一眼能看出来的01背包,但是状态不太好选择,可以选择时间也可以选择高度,其实都差不多,时空要求比较低,我选择高度作为的状态,选择了状态和决策之后,状态转移方程就显而易见了,比较难处理的是对于不能达到时的情况,第一遍提交的时候有一个点没过,就是因为第二种情况没写好,不过其实画个图还蛮好写的。

#include
#include
#include
#include
#include
#define max(a,b) (a>b?a:b)
#define min(a,b) (a
using namespace std;
int sumt,uppon,dp[1010][110],n,d,m;
struct trash{
    int t,f,h;
}tr[110];
int cmp(const trash &a,const trash &b){return a.tint main()
{
    //freopen("std.in","r",stdin);
    sumt=10;uppon=0;
    cin>>d>>n;
    for (int i=1;i<=n;i++)
    cin>>tr[i].t>>tr[i].f>>tr[i].h;
    sort(tr+1,tr+n+1,cmp);
    memset(dp,-1,sizeof(dp));
    dp[0][0]=10;tr[0].t=0;tr[0].f=0;
    for (int i=1;i<=n;i++)
    {
        int c=tr[i].t-tr[i-1].t;
        uppon+=tr[i].h;
        for (int j=uppon;j>=0;j--)
        {
            if (dp[i-1][j]>=c)//注意这里的边界值,题目没有说明,但是样例里已经暗示了 
            dp[i][j]=max(dp[i][j],dp[i-1][j]+tr[i].f-c);
            if (j>=tr[i].h)dp[i][j]=max(dp[i][j],dp[i-1][j-tr[i].h]-c);
            if (j>=d&&dp[i][j]>=0){cout<<tr[i].t;return 0;}
        }       
    }
    int ans=10,k;
    for (int i=1;i<=n;i++)//判断如果到达不了的话
    {
        ans+=tr[i].f;k=sumt;
        sumt=sumt+tr[i-1].t-tr[i].t+tr[i-1].f;
        if (sumt<0){cout<tr[i].f;return 0;}
    }       
    cout<return 0;
}

你可能感兴趣的:(动态规划)