演算法3 揹包問題

2022-04-03 01:47:11 字數 2058 閱讀 2202

揹包問題和01揹包問題是很經典的關於動態規劃和貪心演算法的題目。

這兩個問題很相似,01揹包是有乙個容量為c的揹包,裝入一些質量為w[ ]的且價值為v[ ]的物品,每次只能選擇放入或者不放,不能只放一部分某個物品。求出可以讓揹包裝最大價值的乙個x[ ],其中的每一項表示第 i 個物品是否要裝入。

揹包問題跟01揹包相似,但是可以裝入部分商品。

揹包問題可以用貪心演算法求解,01揹包則要用動態規劃。

先來說01揹包

舉個例子:

c=5,即揹包的容量是5.放入以下質量和價值的物品

編號質量w

價值v016

13122

210根據前面的動態規劃的解法,動態規劃一般需要乙個二維的陣列存放每一步計算得到的動態結果,本例用矩陣 m 表示,行標表示商品編號 用 i 表示,列標表示變化的 j ,即容量01

2345

00610

1618221

001012

122220

0101010

10本例的最佳裝法解x應該是x=,也就是裝入第二個和第三個,總最大價值為12+10=22

我寫了乙個簡單的**

1 #include2

using

namespace

std;

3int m[3][6];//

動態規劃中的矩陣

4int v[3]=;//價值5

int w[3]=;//質量6

int c=5;7

void knapsack()//

v和w的長度都是3828

}29 cout<0][5]<31void

traceback()

3242}43

//計算最後乙個物品是否放入

44int sum=0;45

for(int i=0;i<=1;i++)

4652

if(sum==m[0][5

])53

56else

5760 cout<0]<1]<2

]; 61}

62int

main()

63

要理解01揹包問題,一定要理解這個m矩陣,我換乙個順序再寫一次,假如現在的物品順序變成下面這樣

編號質量w

價值v0312

12102

16那麼矩陣m的變化如下:01

2345

00610

1618221

061016

161620

6666

6要把01揹包問題弄清楚,一定要自己寫一遍這個矩陣。這個矩陣的計算要靠下一行,所以最前面先計算好最後一行。前面的行的結果只能比後面的大,因為m[ i , j ] 表示揹包容量為 j ,可以選擇的物品從i,i+1……n。

所有動態規劃的問題都要很清楚的理解動態規劃的動態矩陣的寫法。

牛客上也有這道題,我寫了乙個版本提交了,牛客網要求輸出揹包可以承受的最大價值。我把輸入輸出改成動態輸入輸出就可以了。

1 #include2

using

namespace

std;

3int knapsack(int c,int *w,int *v,intn)4

25}26return m[0

][c];27}

28void

package()

2937

38 cout<40int

main()

41

寫了乙個c++版本

1 #include2 #include3

using

namespace

std;

4int knapsack(int c,vector w,vector v,intn)5

31 m[i]=tem;32}

33return m[0

][c];34}

35void

package()36

4849 cout<51int

main()

52

揹包問題3(多重揹包)

基於上次說的01揹包和完全揹包,揹包三連發還有最後乙個 多重揹包 什麼事多重揹包,很簡單就是把01揹包和完全揹包結合起來的新揹包問題就叫做多重揹包。有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容...

演算法(揹包問題 01揹包問題)

01揹包問題 有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,...

演算法 揹包問題

揹包問題用逆序減少空間複雜度的情況下,揹包問題,如果是多維揹包 質量,容積,個數 則加矩陣維度 如果是01揹包,則逆序內迴圈,如果是完全揹包 每種物品個數不限 則順序內迴圈,如果是混合揹包 限制每種物品的個數 include using namespace std define maxn 110 d...