具體的工程在我的github上。
乙個正在搶劫商店的小偷發現了n個商品,第i個商品的價值vi元,重wi磅,小偷希望拿走價值盡量高的商品,但是他的揹包只能容納w磅商品,怎麼選擇才能拿走價值最大的商品?
根據演算法導論書上原題和自定一些條件,把這題條件定義如下:
int n = new int;//為了配合演算法,下標都是從1開始,表示每件商品的數量
int w = new int;//表示每件商品的重量
int v = new int;//表示每件商品的價值
int w = 50;//揹包的容積
揹包問題分為兩種:
0-1揹包問題(0-1 knapsack problem):商品不可分,小偷只能完整拿走或者不拿走,或者同乙個商品拿走多次
分數揹包問題(fractional knapsack problem):商品可分,小偷可以拿走商品的部分
問題分析
分數揹包問題
分數揹包問題是典型的貪心演算法,只要計算出商品的每磅價值vi/wi,貪心地選擇每磅價值最高的商品即可
public void fracknapsack(int n, int w, int v, int w)
最優子結構可以表示成下面公式
\\對應的latex公式**,不支援latex真麻煩
f(i,w)=
\begin
f(i-1,w)&&,w_i>w\\
max[f(i-1,w),&f(i-1,w-w_i)+v_i]&,w_i\le w
\end
public void zerooneknapsack(int n, int w, int v, int w) else if (w[i] <= j) {//放入揹包中
int maxprofit = 0;
maxprofit = math.max(result[i - 1][j], result[i - 1][j - w[i]] + v[i]);//選擇放還是不放
result[i][j] = maxprofit;//儲存最優解
system.out.println(result[n.length - 1][w]);
其它揹包問題
完全揹包問題
相比於0-1揹包問題,每件物品的個數已經變成無限個。
求解思路
我們可以轉化為0-1揹包問題來求解,將k件一種物品拆成k種價值一樣的物品,這樣就可以採用上述**寫了。但是這樣寫增大了空間複雜度,也沒有改進時間複雜度。
還有一種方法是轉化成二進位制思想,不太清楚如何寫的,其實思想也是分成0-1揹包問題來解決的
多重揹包問題
介於完全揹包問題和0-1揹包問題之間,第i種物品有n[i]件,其餘條件不變
求解思路
同樣的,可以拆解成0-1揹包問題,這樣的話就大大地增加空間複雜度了
結語通過對揹包問題的學習,基本上困難的演算法問題到最後都是可以求解成最簡單的0-1揹包問題,基礎還是很重要。
變種 揹包問題 演算法設計 揹包問題
題目 乙個旅行者準備隨身攜帶乙個揹包,可以放入揹包的物品有n種,每種物品的重量和價值分別為wj,vj 如果揹包的最大重量限制是b,怎樣選擇放入揹包的物品以使得揹包的價值最大?目標函式 約束條件 演算法設計 設fk y 表示只允許裝前k 種物品,揹包總重不超過y 時揹包的最大價值。fk y 有兩種情況...
個人筆記 演算法講座3 揹包問題及其變種
設計乙個動態規劃問題需要首先搞清楚他的 同質子結構 狀態轉移方程 備忘錄 即動態規劃中動態儲存資料的東西 如果將揹包問題用方程 f w,i 表示 w 為揹包容量,i 為物品個數 則對於每乙個物品,只需要考慮裝入揹包 or 不裝入揹包這兩個情況 對於 f 4,3 9 i 3 weight 8,valu...
演算法導論 0 1揹包問題 與 部分揹包
0 1揹包 問題描述 n件物品,第i件物品價值 v i 元,重w i 磅。希望用 w磅的書包 拿走總價值最貴的物品。物品不可以分割故稱為0 1揹包 部分揹包 問題描述 n件物品,第i件物品價值 vi 元,重wi 磅。希望用 w磅的揹包 拿走最重的物品。第i件物品可以都拿走,也可以拿走一部分。物品可以...