小偷發現了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...