【POJ - 2392】Space Elevator (dp,优秀的背包问题)
題干:
The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000).?
Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.
Input
* Line 1: A single integer, K?
* Lines 2..K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.
Output
* Line 1: A single integer H, the maximum height of a tower that can be built
Sample Input
3 7 40 3 5 23 8 2 52 6Sample Output
48Hint
OUTPUT DETAILS:?
From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.
題目大意:
給出了一些磚塊,磚塊有高度,最高可以達到的高度(高度限制)和數量,問最高可以摞多高的塔。
解題報告:
? ? ?首先按照限制高度排序這點沒問題吧。反正我早晚都得排序,還不如先排那些可能被高度限制住的。
? 我們都知道,多重背包可以轉化成0-1背包類模板的問題去求解,也可以轉化成完全背包類模板去求解,即,一個是正向遍歷,一個是反向遍歷(內層循環的時候),
AC代碼:(多重背包轉完全背包模型去求解,即正向遍歷的模型,然后把那些限制都變成一個個的if判斷就好了。)
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #define ll long long using namespace std; struct Node {int h,a,c; } node[500]; int dp[40000 + 5]; int sum[40000 + 5];bool cmp(const Node &a,const Node &b) {return a.a<b.a;} int main() {int ans = 0;int KK;cin>>KK;//for(int i =1; i<=KK; i++) {scanf("%d%d%d",&node[i].h,&node[i].a,&node[i].c);}sort(node + 1,node+KK+1,cmp);dp[0] = 1;for(int i = 1; i<=KK; i++) { // for(int k = 1; k<=node[i].c; k++) // for(int j =40000; j>=node[i].a; j--) { // dp[j] = max(dp[j]) // }memset(sum,0,sizeof(sum));//記錄當前這個物品在j高度(相當于是體積)for(int j = node[i].h; j <= node[i].a; j++) {if(dp[j] == 0 &&dp[j - node[i].h ] == 1&& sum[j -node[i].h ] + 1 <= node[i].c) {//如果dp[j]當前高度更新過了,那就不再更新,因為我們可以留著這一塊磚頭放到更高的地方。sum[j ] = sum[j -node[i].h ] + 1;dp[j] = 1;ans = max(ans,j);}}}printf("%d\n",ans);return 0 ; }或者:(多重背包轉換成0-1背包去求解,b結構體為node這個多重背包的結構體 ?經過二進制優化后存入的結構體)
注意的就是最后最大高度的dp[node[KK].a ]不一定是最優解
因為這個dp[node[KK].a ]的最值是從上一步過來的
而由于上一步dp的 ?node[KK].a 更小,因此dp數組存在斷檔
所以要最后從頭掃一遍才能得出最優解,或者直接在線維護一個maxx就可以了
sort(b+1,b+p,cmp);int maxx = 0;for(int i=1;i<p;++i){for(int j=b[i].a;j>=b[i].h;--j){ //背包容量從cost開始才有效dp[j] = max(dp[j],dp[j-b[i].h]+b[i].h); maxx = max(maxx,dp[j]);}}cout<<mmax<<endl;?
總結
以上是生活随笔為你收集整理的【POJ - 2392】Space Elevator (dp,优秀的背包问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知识点 组合数学 卡特兰数
- 下一篇: 信用卡逾期可以贷款吗 这些损失你必须承受