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; }