01揹包問題

2021-09-13 12:41:12 字數 1167 閱讀 3379

動態規劃(dynamic programming,dp)與分治區別在於劃分的子問題是有重疊的,解過程中對於重疊的部分只要求解一次,記錄下結果,其他子問題直接使用即可,減少了重複計算過程。 

另外,dp在求解乙個問題最優解的時候,不是固定的計算合併某些子問題的解,而是根據各子問題的解的情況選擇其中最優的。 

動態規劃求解具有以下的性質: 

最優子結構性質、子問題重疊性質   

最優子結構性質:最優解包含了其子問題的最優解,不是合併所有子問題的解,而是找最優的一條解線路,選擇部分子最優解來達到最終的最優解。 

子問題重疊性質:先計算子問題的解,再由子問題的解去構造問題的解(由於子問題存在重疊,把子問題解記錄下來為下一步使用,這樣就直接可以從備忘錄中讀取)。其中備忘錄中先記錄初始狀態。

①、將原問題分解為子問題(子問題和原問題形式相同,且子問題解求出就會被儲存); 

②、確定狀態:01揹包中乙個狀態就是個物體中第個是否放入體積為揹包中; 

③、確定一些初始狀態(邊界狀態)的值; 

④、確定狀態轉移方程,如何從乙個或多個已知狀態求出另乙個未知狀態的值。(遞推型)

①、確認子問題和狀態 

01揹包問題需要求解的就是,為了體積v的揹包中物體總價值最大化,件物品中第件應該放入揹包中嗎?(其中每個物品最多只能放一件) 

為此,我們定義乙個二維陣列,其中每個元素代表乙個狀態,即前個物體中若干個放入體積為揹包中最大價值。陣列為:,其中表示前件中若干個物品放入體積為的揹包中的最大價值。 

②、初始狀態 

初始狀態為和都為0,前者表示前0個物品(也就是空物品)無論裝入多大的包中總價值都為0,後者表示體積為0的揹包啥價值的物品都裝不進去。 

③、轉移函式

if (揹包體積j小於物品i的體積)

f[i][j] = f[i-1][j] //揹包裝不下第i個物體,目前只能靠前i-1個物體裝包

else

f[i][j] = max(f[i-1][j], f[i-1][j-vi] + wi)

最後一句的意思就是根據「為了體積v的揹包中物體總價值最大化,件物品中第件應該放入揹包中嗎?」轉化而來的。表示第件物體的體積,表示第件物品的價值。這樣f[i-1][j]代表的就是不將這件物品放入揹包,而f[i-1][j-vi] + wi則是代表將第i件放入揹包之後的總價值,比較兩者的價值,得出最大的價值存入現在的揹包之中。

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