01揹包問題
阿新 • • 發佈:2020-07-17
分析:
題目要求求得的是揹包容量為c,有n個物品可選時的最大價值。很明顯它有一個子結構,題目要求的結果可表示為dp[n][c],子問題dp[i][j]
表示揹包容量為j,可選擇物品為1~i時的最大價值。
狀態轉移公式為:
當j<w[i]時,dp[i][j]=dp[i-1][j]
當w[i]<=j<=c時,dp[i][j]=max(dp[i-1][j-w[i]]+v[i],dp[i-1][j])
const int c = 10;//總容量; const int n = 5;//物品數; vector<int> backpack(int v[], int w[]) { int dp[n + 1][c + 1];//dp[i][j]表示揹包容量為j,可選擇物品為1~i時的最大價值,代表一個子問題的解; vector<int> x(n, 0);//判斷是否放第i個物品; for (int j = 0; j <= c; ++j) dp[0][j] = 0; for (int i = 0; i <= n; ++i) dp[i][0] = 0; for (int i = 1; i <=n; ++i) {//依次對物品進行遍歷 for (int j = 1; j < w[i] && j < c; ++j)//裝不下第i個物品 dp[i][j] = dp[i - 1][j]; for (int j = w[i]; j <= c; ++j)//裝得下第i個物品,但是裝還是不裝要看哪個的總價值更大 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); } //求出x int spare = c; for (int i = n; i > 0; --i) //要從dp[n][c]開始計算 if (dp[i][spare] == dp[i - 1][spare]) x[i - 1] = 0; else { x[i - 1] = 1; spare -= w[i]; } return x; }