最通俗易懂的01揹包問題講解

2021-09-13 02:49:11 字數 1681 閱讀 8395

1、動態規劃(dp)

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

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

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

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

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

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

2、求解思路

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

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

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

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

3、01揹包問題求解思路

①、確認子問題和狀態 

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

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

②、初始狀態 

初始狀態為f[0][0−v]f[0][0−v]和f[0−n][0]f[0−n][0]都為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)12

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

4、程式

#include

using namespace std;

int main()

};int ncost[6] = ;  //花費

int nvol[6]   = ; //物體體積

int ba** = 12;

for( int i = 1; i< sizeof(ncost)/sizeof(int); i++)

01揹包問題其實就可以化簡為塗寫下面的**,其中每個數對應陣列narr中每個元素,初始化部分為0,然後從左上角按行求解,一直求解到右下角獲取最終解narr[5][12]。 

動態規劃 01揹包問題(通俗易懂,超基礎講解)

問題描述 有n個物品,它們有各自的體積和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?為方便講解和理解,下面講述的例子均先用具體的數字代入,即 eg number 4,capacity 8 i 物品編號 1 2 3 4 w 體積 2 3 4 5 v 價值 3 4 5 6 總體思...

動態規劃 01揹包問題(通俗易懂,超基礎講解)

問題描述 有n個物品,它們有各自的體積和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?為方便講解和理解,下面講述的例子均先用具體的數字代入,即 eg number 4,capacity 8 i 物品編號 1 2 3 4 w 體積 2 3 4 5 v 價值 3 4 5 6 總體思...

動態規劃 01揹包問題(通俗易懂,超基礎講解)

我只是來單純學習怎麼寫部落格的,嘿嘿 有n個物品,它們有各自的體積和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?為方便講解和理解,下面講述的例子均先用具體的數字代入,即 eg number 4,capacity 8 i 物品編號 12 34w 體積 23 45v 價值 34 ...