1.揹包問題
(1)問題由來:給定n個重量為w1,w2..........wn,價值為v1,v2........,vn的物品和乙個承重為w的揹包,求這些物品中最有價值的乙個子集,並要求能夠裝到揹包中。這裡假設所有的重量和包的承重都是正整數,而物品的總重量不必是整數。
(2)地推公式:為了設計乙個動態規劃演算法,需要推導乙個遞推關係,用較小例項解的形式來表示揹包問題的例項的解。接下來我們來考慮乙個由前i個物品定義的例項,物品的重量分別w1,w2,w3,..wi,價值分別為v1,v2,.........vi,揹包承受的重量為j(j>=1,j<=w)。設f(i,j)為該例項最優解的物品總價值,也就是說能夠放進承重為j的揹包中的前i個物品中最有價值自己的總價值。可以將前i個物品中能夠放進承重為j的揹包中的子集分為兩個類別:包括第i個物品的子集和不包括第i個物品的子集。
(3)根據上面的描述有下面的結論:
根據定義,在不包括第i個物品的子集中,最優子集的價值為f(i-1,j)。
在包括第i個物品的子集中,最優子集是由該物品和前i-1個物品中能夠放進承重為j-wi的揹包的最優子集組成。這種最優子集的價值為vi+f(i-1,j-w)
(4)因此,在前i個物品中最優解的總價值為兩個價值中的較大值。當然如果第i個物品不能夠放進揹包,則從前i個物品中選出的最優子集的總價值等於從前i-1個物品中選出的最優子集的總價值。這個結果又下面的遞推公式。
我們可以比較容易的定義如下的初始條件:當j>=0的時候,f(0,j)=0;當i>=0的時候,f(i,0)=0
我們的目標是f(n,w),即n個給定的物品中能夠放進承受重量為w的揹包中的子集的最大總價值以及最優子集本身。當i,j>0的時候,為了計算第i行第j列的單元格f(i,j),我們拿前一行同一列的單元格與vi加上前一行左邊wi列的單元格的和作比較,計算出兩者的較大者。
(5)例項:考慮下列資料給出的例項
下圖給出了由動態規劃公示計算的動態規劃表
最大的總價值為f(4,5)=37可以通過上表回溯過程來求得最優子集元素,因為f(4,5)=37,f(3,5)=32,物品4填滿揹包餘下5-2=3個單位承重量的乙個最優子集都包括在最優解中。
(6)記憶化
動態規劃所涉及問題的解滿足乙個交疊子問題來表示遞推關係。直接使用自頂向下的這樣乙個地推關係求解導致演算法要不止一次的求解公共子問題,因此演算法的效率比較低(一般來說是指數級的),另一方面經典動態規劃是自底向上工作的,它用所有較小的子問題來填充**,但是每個子問題只解一次,這種方法無法令人滿意的一面是,在求解給定問題時,有些較小子問題的解常常不是必須的。所以我們使用記憶法,該方法使用自頂向下的方式對給定問題進行求解,但是還需要維護乙個類似自底向上動態規劃演算法使用的**。演算法思想如下:
2.例項:
packagecom.nowcoder.dp;
import
org.junit.test;
public
class
knapsack
/***
* @param
val 例項最優解的最大值
* @param
wight 物品的重量
* @param
w 揹包容量
* @return
*/public
static
int knapsack(int val,int wight,int
w)
//對於第0列所有的行來說,揹包容量為0,不能再向揹包中放任何物品
for(int row = 0 ; row <= n ;row++)
/*** 接下來填充記錄表
*/for(int i = 1 ; i <=n;i++)
else }}
return
v[n][w];
}@test
public
void
test();
int wight=;
int w = 10;
system.out.println(knapsack(val,wight,w));}}
揹包問題 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...