揹包問題 01揹包掃盲 動規五步法

2021-10-22 23:11:09 字數 2036 閱讀 5814

參考:動態規劃:關於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...