0 1揹包問題

2021-10-08 08:43:52 字數 1895 閱讀 2198

問題描述:

給出揹包的容積,商品的**和商品的體積,在不超過揹包容量的情況下,買走**最大的商品。

(所謂0-1,就是每件商品最多只能選一次,所以這是個很基礎的動態規劃問題)

商品如下:

方法1:回溯演算法

該演算法基於以遞迴的方式建立的列舉演算法。

列舉遞迴的基本思想:要求剩餘i件商品,揹包剩餘容積為c時的最大**(最優解),只需要求(剩餘i-1件商品,揹包剩餘容積為c時的最優解)和的最大值。 因為剩餘i-1種商品有兩種情況:

1·選了第i種商品

2·沒有選第i種商品

按照這樣分解下去就能把所有情況都能考慮

方法二:遞推求解演算法

回溯演算法的缺點是要遞推後還得遞迴,有點費時,我們發現,不用遞迴,可以直接遞推求解。

由於best[i][c]是依靠best[i-1][c]和best[i-1][c-v[i]]+p[i]比較求出,,又為從小到大求解best,所以best[i][c]表要填滿,才能確保後面得情況能被順利求出來

best[i][c]求得結果如圖

從表中可知,i=5,c=13的最優解為28

下面分析is_sel**,即在剩餘i件物品,容量為c的情況下,第i件商品有沒有選擇的**。

如何分析選了哪種商品?

我們要分析先分析在i=5,c=13時是否選了第五種商品

如圖可知在i=5,c=13時選了第5種商品–牛奶

再分析在i=4,c=13-4=9的時候是否選了第4種商品

如圖可知在i=4,c=9時選了第4種商品–麵包

再分析在i=3,c=9-5=4的時候是否選了第3種商品

如圖知沒有在i=3,c=4的時候選第3種商品

則分析在i=2,c=4的時候是否選了第3種商品

如圖可知在i=2,c=4時選了第2種商品–餅乾

c-4=0;結束。

(這種方法只能選擇一種情況,要是在i=某個數時,既可以選這個商品,也可以不選這個商品,這就不能顧及周全)

#include

using

namespace std;

#define min_inf -2147483648

// 各種商品的**,從1開始

int p[6]

=;// 上面幾種商品對應的體積,從1開始

int v[6]

=;// 記錄是否在揹包剩餘該容積情況下選擇了該商品(初始化為0,表示沒選擇)

int is_sel[6]

[14]=

;// 容量從0到13,所以,二維陣列第二維大小為14

// 記錄第剩餘容積c時,剩餘i個商品的最優解,做到記憶化搜尋,防止重複浪費時間,預設初始化為0;

int best[6]

[14];

// 直接用遞推的方法求最優解

intknapsacksr

(int i,

int c)

else

}// 要是剩餘的容積比第i件商品的體積都小,則第i件商品不能選

else

}return best[i]

[c];

}void

show_seletion()

}}cout << endl;

}int

main()

揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...

揹包問題 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...