Space Elevator POJ 2392(多重背包dp)

原题

题目链接

题目分析

多重背包题,在放入的时候需要按a的大小排序.定义dp[i][j]为前i个积木凑成j高度,第i个物品最多剩下多少,然后j从0遍历到a[i],dp初始化为-1,dp[0][0]=0.更新方式跟多重背包完全一样,if(dp[i-1][j]!=-1) dp[i][j]=c[i];else if(j>=h[i]&&dp[i][j-h[i]]>0) dp[i][j]=dp[i][j-h[i]]-1;由更新方向可知可以状压,把第一维压掉,第二维j从小到大遍历即可.最后从dp数组中找一个最大的j即为答案.

代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <utility>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <queue>
11 #include <map>
12 #include <set>
13 
14 using namespace std;
15 typedef long long LL;
16 const int INF_INT=0x3f3f3f3f;
17 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
18 
19 struct N
20 {
21     int h,a,c;
22 }block[500];
23 
24 bool cmp(N x,N y)
25 {
26     return x.a<y.a;
27 }
28 
29 int dp[50000];
30 
31 int main()
32 {
33 //    freopen("black.in","r",stdin);
34 //    freopen("black.out","w",stdout);
35     int k;
36     cin>>k;
37     for(int i=1;i<=k;i++) cin>>block[i].h>>block[i].a>>block[i].c;
38     sort(block+1,block+1+k,cmp);
39 //    for(int i=1;i<=k;i++) printf("block %d h=%d a=%d c=%d\n",i,block[i].h,block[i].a,block[i].c);
40     for(int j=0;j<=block[k].a;j++) dp[j]=-1;
41     for(int i=1;i<=k;i++)
42     {
43         dp[0]=block[i].c;
44         for(int j=1;j<=block[i].a;j++)
45         {
46             if(dp[j]!=-1) dp[j]=block[i].c;
47             else if(j>=block[i].h&&dp[j-block[i].h]>0) dp[j]=dp[j-block[i].h]-1;
48         }
49 //        for(int j=0;j<=block[].a;j++) printf("dp %d %d=%d\n",i,j,dp[j]);
50     }
51     int ans=block[k].a;
52     while(dp[ans]==-1) ans--;
53     cout<<ans<<endl;
54     return 0;
55 }

 

posted @ 2019-08-26 19:28  VBL  阅读(124)  评论(0编辑  收藏  举报