【經典動態規劃問題】0-1揹包問題
阿新 • • 發佈:2018-12-30
0,1揹包問題
一個揹包有一定的承重cap,有N件物品,每件都有自己的價值,記錄在陣列v中,也都有自己的重量,記錄在陣列w中,每件物品只能選擇要裝入揹包還是不裝入揹包,要求在不超過揹包承重的前提下,選出物品的總價值最大。
每個物品只有1個,給定物品的重量w價值v及物品數n和承重cap。請返回最大總價值。
狀態:dp[i][j] 儲存物品0,...i儲存到承重為j的揹包中的最大價值
邊界討論:
當i等於0時,也就是說只有一個物品,重量為w[0],價值為v[0],那麼只有當j>= w[0]時,dp[0][j] = v[0];
當j等於0時,即揹包承重為0,不可能裝下任何物品,此時dp[i][0] = 0;
一般性的狀態討論:
對於當前的物品i,如果把這個物品裝入揹包(承重為j),揹包裡物品總價值是多少?
等於0,...i-1件物品的最大總價值+當前物品價值 也就是dp[i-1][j-w[i]]+v[i],注意此時留給0,...i-1物品的揹包承重為j-w[i],因為已經確定取索引為i的物品,這個物品會佔據w[i]的重量。
如果不裝入揹包(承重為j),揹包裡物品總價值為dp[i-1][j],也就是0,....i-1件物品放入承重為j的最大價值。
class Backpack { public: int maxValue(vector<int> w, vector<int> v, int n, int cap) { // write code here int dp[500][500] = {0};//dp[i][j]指的是0,...i件物品,裝到j承重的包中的最大價值 for(int k = 0;k <=cap;k++){//i = 0,只有第一件物品時,每件物品只有一個 if(k>=w[0])//k表示容量 dp[0][k] = v[0]; } for(int i = 0;i<n;i++){//j = 0,承重為0時 dp[i][0] = 0; } for(int i = 1;i<n;i++){ for(int j = 1;j<=cap;j++){ if(j>=w[i])//剩餘承重可以放w[i] dp[i][j] = (dp[i-1][j-w[i]]+v[i])> dp[i-1][j]?(dp[i-1][j-w[i]]+v[i]):dp[i-1][j]; else dp[i][j] = dp[i-1][j]; } } return dp[n-1][cap]; } };
注意初始化時0-1揹包問題的限定,即當只能取第一件物品時,j>w[0]的所有情況都是一樣的,即揹包中只能放下一件物品。