演算法導論16 2 2 動態規劃(0 1揹包問題)

2021-08-10 06:16:45 字數 3140 閱讀 1238

小偷發現了n個商品,第i個商品重量為wi

,價值為vi

。小偷希望盡量拿走價值高的商品,但是他的揹包只能容納w重的商品。求如何取捨這些商品? 

由於對乙個商品,要麼被拿走要麼不被拿走,所以被稱為0-1揹包問題。 

我們如果採取列舉法進行比較,將會有2n

個情況,演算法複雜度與n呈指數關係。 

下面分析揹包問題的性質:令x

i =1,表示第i個商品被拿走,xi

=0,表示第i個商品不被拿走。 

則問題變為求v=

max∑

ni=1

xivi

約束條件為∑n

i=1x

iwi≤

w ,求最大值的x1

,x2,

x3..

xn解; 

對於第k個商品,決定是否裝包,需要進行比較,如果拿裝包即xk

=1,求子問題v′

=max

∑ni=

1xiv

i(i≠

k),約束條件為∑n

i=1x

iwi(

x≠k)

≤w−w

k 。如果不裝包,xk

=0,v′′=

max∑

ni=1

xivi

(i≠k

) ,約束條件不變∑n

i=1x

iwi(

x≠k)

≤w。比較v′

與v′′ 大小。

演算法複雜度為o(nw) 

令c[i][j]表示第1個商品到第i個商品中,揹包容量為j的情況下,可獲得的最大價值;

決定是否選擇商品i的方案,比較選與不選的獲得的價值 

c[i][j] = max(c[i-1][j] ,v[i]+c[i-1][j-w[i]]) 

例:

int w=;//商品重量 第一數值為0,為了方便程式設計

int v=;//商品價值 第一數值為0,為了方便程式設計

int w = 10; //揹包容量

int c[6][11]=;//c[i][j]表示在商品1到i中,揹包容量為j時,最大價值

採用自底向上求解方案,先填寫第一行c[1][j],此時只有商品1可選,當j1]

時,揹包容量小於商品1的大小,所以c[1][j] =0,當j≥

w[1]

時,揹包內價值即為商品1的價值c[1][j] = v[1]=4; 

填寫第二行:c[2][j],此時可選商品為1和2 。當j2]

,商品2一定裝不了,但可能裝下商品1,所以即c[2][j] = c[1][j],當j≥

w[2]

,此時可以裝下商品2,如當j=6時,如果選擇商品2,那麼此時揹包容量為j-w[2]=0,留給商品1用,而c[1][0]=0,所以揹包價值為c[2][6]=v[2]+c[1][0];如果不選商品2,則c[2][6]=c[1][6]=4,比較大小得到,應該把商品2裝包。即c[2][6]=v[2]+c[1][0]=6+0=6; 

又如:當j=10時,如果選擇商品2,則揹包容量還剩j-w[2]=4;而c[1][4]=4,此時揹包總價值為c[2][10]=v[2]+c[1][4]=6+4=10;如果不選商品2,c[2][10] =c[1][10]=4;選取最大值即c[2][10]=10; 

按照上述方式自底向上填寫**: 

按照上面描述:如果c[i][j] = c[i-1][j],表明商品i沒有被選擇;否則就被選擇 

從**的右下端開始,即c[5][10],回溯。 如c

[5][

10]≠c

[4][

10]則商品5被選擇,而此時揹包容量j-w[5]=4;繼續向上回溯,比較c[4][4]=c[3][4],表明商品4不選。回溯到第乙個商品時,如果c[

1][j

]≠0 ,表明被裝包;

/*****
*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*******

csdn 勿在浮沙築高台

演算法導論--動態規劃(0-1揹包問題)

2023年6月19日

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*****

*******/

#include

using namespace std;

#define max(a,b) (((a) > (b)) ? (a) : (b))

int w=;//商品重量

int v=;//商品價值

int w = 10; //揹包容量

int c[6][11]=;//c[i][j]表示在商品1到i中,揹包容量為j時,最大價值

void package0_1(int w,int v,int w,int n,int c[11])//

else

else}}

}for(int m =1;m<6;m++)

cout

}void print_package0_1(int c[11]) //構造解

else

i--;

}if ( c[i][j] == 0) //

else

}int main()

演算法導論 01揹包問題 (動態規劃)

描述 有編號分別為n i 的五件物品,它們的重量分別是6,9,14,16,19,它們的價值分別是8,13,25,44,22,現在給你個承重為30的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?遞迴求解 include include using namespace std const int we...

演算法導論03 動態規劃 01揹包問題

public class test int weight sort value,0,value.length 1 sort weight,0,weight.length 1 system.out.println value arrays.tostring value system.out.print...

演算法之動態規劃 0 1揹包

經典的盜賊問題 乙個盜賊帶著乙個揹包去偷東西,房中有五件物品 1 6公斤 48元 2 5公斤 40元 3 2公斤 12元 4 1公斤 8元 5 1公斤 7元 但是他的揹包只能裝下8攻擊的東西 問他該怎樣選擇保障拿到的東西價值最大。思路 使用動態規劃來實現,1.將物品i 放到揹包裡面,修改選擇標誌 2...