洛谷·積木城堡
【揹包問題】
初見安~這裡是傳送門:洛谷P1504
題目
XC的兒子小XC最喜歡玩的遊戲用積木壘漂亮的城堡。城堡是用一些立方體的積木壘成的,城堡的每一層是一塊積木。小XC是一個比他爸爸XC還聰明的孩子,他發現壘城堡的時候,如果下面的積木比上面的積木大,那麼城堡便不容易倒。所以他在壘城堡的時候總是遵循這樣的規則。
小XC想把自己壘的城堡送給幼兒園裡漂亮的女孩子們,這樣可以增加他的好感度。為了公平起見,他決定把送給每個女孩子一樣高的城堡,這樣可以避免女孩子們為了獲得更漂亮的城堡而引起爭執。可是他發現自己在壘城堡的時候並沒有預先考慮到這一點。所以他現在要改造城堡。由於他沒有多餘的積木了,他靈機一動,想出了一個巧妙的改造方案。他決定從每一個城堡中挪去一些積木,使得最終每座城堡都一樣高。為了使他的城堡更雄偉,他覺得應該使最後的城堡都儘可能的高。
任務:
請你幫助小XC編一個程式,根據他壘的所有城堡的資訊,決定應該移去哪些積木才能獲得最佳的效果。
輸入格式:
第一行是一個整數N(N<=100),表示一共有幾座城堡。以下N行每行是一系列非負整數,用一個空格分隔,按從下往上的順序依次給出一座城堡中所有積木的稜長。用-1結束。一座城堡中的積木不超過100塊,每塊積木的稜長不超過100。
輸出格式:
一個整數,表示最後城堡的最大可能的高度。如果找不到合適的方案,則輸出0。
輸入輸出樣例
輸入樣例:
2
2 1 –1
3 2 1 –1
輸出樣例:
3
題解:
本題要求每個城堡一樣高且儘量高,即求每個城堡都可達到的最大高度,所以可以將這些城堡看做只是分了堆的積木,列舉每個城堡可達到的高度,最後達到的城堡數量正好為n個城堡的最大高度即為所求。
思路看起來很簡單(卡了我一個多小時 ),重點在於:如何列舉每個城堡可以達到的高度?如果全用for迴圈來列舉的話,會比較麻煩,所以——可以用到揹包問題的思路(說白了還是列舉 )
但從大到小列舉的原因——你們可以手動樣例試一下(懶得解釋 ),一開始是為了避免重複(後來發現避免不了就懶得改了 )。
程式碼如下——
#include<bits/stdc++.h> using namespace std; bool dp[30000]; int n; int a[100]; int ans[100000]; int maxn; int main() { cin>>n; for(int i=1;i<=n;i++) { memset(dp,0,sizeof dp); dp[0]=1; int t=0,sum=0; int x; while(666) { cin>>x; if(x<0) break; a[++t]=x; sum+=x; } if(sum>maxn) maxn=sum; for(int j=1;j<=t;j++) { for(int k=sum;k>=a[j];k--) { if(dp[k-a[j]]&&!dp[k]) { dp[k]=1; ans[k]++; } } } } for(int i=maxn;i>=1;i--) { if(ans[i]==n) { cout<<i<<endl; return 0; } } cout<<0<<endl; return 0; }
迎評:)
——End——