參考:動態規劃:關於01揹包問題,你該了解這些!物品數量為
n
,每個物品的重量為weight[i],i∈[1, n]
,對應的物品價值為value[i], i∈[1, n]
,每件物品只有一件,問題是:將哪些物品放進揹包後,揹包中的價值總和最大?
1、確定dp陣列與下標含義:
dp[i] [j]
表示從下標[0-i]
內的物品任意取,存放進容量為j
的揹包後,最大價值總和是多少。也就是,行索引i
使用者來遍歷物品,列索引j
用來遍歷揹包容量。遍歷物品能理解,那麼為什麼要遍歷揹包容量呢?這是因為需要一點點增加揹包容量,直到容量為j
,表明是有狀態轉移存在的,因此才可以用動態規劃來解決。
dp[i] [j]
陣列形式如下:
dp[i][j]
0 1 2 3 4 5
物品0:
物品1:
物品2:
2、確定遞推公式:
一般二維dp陣列會從行索引與列索引兩個方向上求出狀態遞推。
那麼遞推公式顯而易見了,dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]])
其實不推導,直接解讀遞推公式的話,也是比較容易理解的。dp[i-1][j]
代表:不將物品i
放入揹包的最大價值。dp[i-1][j-weight[i]] + value[i]
表示:將物品i
放進揹包之後的最大價值。兩者之中的最大值就是dp[i][j]
。
3、dp陣列的初始化
二維dp陣列初始化就是看兩條邊。
4 、確定遍歷順序
可以先遍歷物品i
(dp陣列行索引),再遍歷揹包容量j
(dp陣列列索引)
5、舉例推導dp陣列
假設物品資訊如下
重量 價值
物品0 1 15
物品1 3 20
物品2 4 30
dp[i]
[j]012
34物品0: 0
1515
1515
物品1: 0
1515
2035
物品2: 0
1515
2035
完整**如下:
void
test_2_wei_bag_problem1()
; vector<
int> value =
;int bagweight =4;
// 二維陣列
vectorint>>
dp(weight.
size()
+1, vector<
int>
(bagweight +1,
0));
// 初始化
for(
int j =
0; j <= bagweight;
++j)
// weight陣列的大小 就是物品個數
for(
int i =
1; i < weight.
size()
; i++)}
cout << dp[weight.
size()
-1][bagweight]
<< endl;
}int
main()
分支限界法01揹包問題 01揹包問題
1.01揹包問題的描述 有n個不可分割的物品,它們有各自的重量和價值,現有固定容量的揹包,選擇把哪些物品放入揹包可以讓揹包中物品的價值最大。2.錯覺 按照價值和重量的比值 價效比 進行排序,依次嘗試放入直到放不進揹包為止。但是細想思考一下就能發現,這個貪心演算法是有問題的,看下面乙個例子。揹包容量1...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...