問題描述:
給出揹包的容積,商品的**和商品的體積,在不超過揹包容量的情況下,買走**最大的商品。
(所謂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...