蘋果
- 描述
-
ctest有n個蘋果,要將它放入容量爲v的揹包。給出第i個蘋果的大小和價錢,求出能放入揹包的蘋果的總價錢最大值。
- 輸入
- 有多組測試數據,每組測試數據第一行爲2個正整數,分別代表蘋果的個數n和揹包的容量v,n、v同時爲0時結束測試,此時不輸出。接下來的n行,每行2個正整數,用空格隔開,分別代表蘋果的大小c和價錢w。所有輸入數字的範圍大於等於0,小於等於1000。
- 輸出
- 對每組測試數據輸出一個整數,代表能放入揹包的蘋果的總價值。
- 樣例輸入
-
3 3 1 1 2 1 3 1 0 0
- 樣例輸出
-
2
- 來源
/* 01揹包問題,最基本的揹包型動態規劃問題 設dp[i][j] 表示從前i個物體中選擇,在體積不超過j的情況下所得到的最大價值 有以下兩種情況: 1.當無法放入第i個物體,則在j的體積下所獲得最大價值由i-1個物體所決定 2.當放入第i個物體 所以獲得最大價值爲前i-1個物體放入體積爲j-w[i]的揹包中所獲得最大價值 於是動態轉移方程爲: dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]) (其中w[]存放每件物品的體積,v[]存放每件物體的價值) */ #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #define MAX 1005 using namespace std; int c[MAX],w[MAX]; int dp[MAX][MAX]; int main(){ int n,v; while(cin>>n>>v){ if(n==0 && v==0) break; else{ memset(c,0,sizeof(c)); memset(w,0,sizeof(w)); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ int C,W; cin>>C>>W; c[i]=C,w[i]=W; } for(int i=0;i<n;i++){ for(int j=0;j<=v;j++){ if(j<c[i]){ dp[i+1][j]=dp[i][j]; } else dp[i+1][j]=max(dp[i][j],dp[i][j-c[i]]+w[i]); } } cout<<dp[n][v]<<endl; } } }
/* 優化: 用一位數組存儲dp[] dp[i]表示體積爲i的情況下所獲得最大價值有之前的二維數組的思路可得動態轉移方程 dp[i]=max(dp[i],dp[i-w[i]]+v[i]) */ #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #define MAX 1005 using namespace std; int c[MAX],w[MAX]; int dp[MAX]; int main(){ int n,v; while(cin>>n>>v){ if(n==0 && v==0) break; else{ memset(c,0,sizeof(c)); memset(w,0,sizeof(w)); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ int C,W; cin>>C>>W; c[i]=C,w[i]=W; } for(int i=0;i<n;i++){ for(int j=v;j>=c[i];j--){//注意循環方向,從最大體積到第i個物體體積,因爲dp[j]的價值需要根據 dp[j-c[i]]來確定 dp[j]=max(dp[j],dp[j-c[i]]+w[i]); } } cout<<dp[v]<<endl; } } }