P1156 垃圾陷阱

链接:Miku

------------

这是一道背包,但是对于放东西有条件限制

----------

首先思考,对于每一个物品,除非放不了,否则就要放,不放上就吃掉,肯定不能扔那不管

-----------

我们定义dp[i][j]为第i个物品,高度为j的时候能活的最长时间,那么整个转移过程就是

for(int i=1;i<=g;++i){
        for(int j=0;j<=d;++j){
            if(dp[i-1][j]>=ru[i].t){//如果能活到的话才会转移,不然就是0,活不到啊
                dp[i][j]=max(dp[i][j],dp[i-1][j]+ru[i].f);//如果吃了它
                dp[i][j+ru[i].h]=max(dp[i-1][j],dp[i][j+ru[i].h]);//如果用来垫着
                if(j+ru[i].h>=d){
                    cout<<ru[i].t<<endl;//因为我们按时间枚举,所以跳出就行了
                    return 0;
                }
            }
        }
        ans=max(ans,dp[i][0]);//最大时间肯定是全吃了,不过可能在某一刻活不到下一个垃圾o
    }

注意,每一个状态可能从两个状态转移过来,所以要取max

----------------

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct r{
    int t;
    int f;
    int h;
}ru[1001];
int d,g;
int dp[1001][20001];
int cmp(r x,r y){
    return x.t<y.t;
}
int ans;
int ff;
int main(){
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;++i){
        cin>>ru[i].t>>ru[i].f>>ru[i].h;
    }
    sort(ru+1,ru+g+1,cmp);
    dp[0][0]=10;
    for(int i=1;i<=g;++i){
        for(int j=0;j<=d;++j){
            if(dp[i-1][j]>=ru[i].t){
                dp[i][j]=max(dp[i][j],dp[i-1][j]+ru[i].f);
                dp[i][j+ru[i].h]=max(dp[i-1][j],dp[i][j+ru[i].h]);
                if(j+ru[i].h>=d){
                    cout<<ru[i].t<<endl;
                    return 0;
                }
            }
        }
        ans=max(ans,dp[i][0]);
    }
    cout<<ans;
    return 0;
}
Ac

 

posted @ 2020-02-07 21:04  Simex  阅读(152)  评论(0编辑  收藏  举报