動態規劃 揹包問題

2022-06-25 02:36:09 字數 2334 閱讀 8324

一、01揹包問題

有n個重量和價值分別為wi,vi 的物品。從這些物品中挑選出總重量不超過w的物品,求所有挑選方案中價值總和最大的乙個。

1:樸素演算法

對於每個物品,有可選與不可選兩種可能,這取決於揹包是否還能裝入。若可取,則判斷取之前與之後兩種選擇哪種最終價值總和更大。搜尋所有可能。

1

//輸入

2int

n,w;

3int

w[max_n],v[max_n];45

//i:物品下標 val:當前揹包剩餘容量 返回最大總價值

6int rec( int i, int

val )712

13int res = 0;14

if( w[i]>val )

15

18else

19

22return

res;23}

2425

void

solve()

26

view code

這種方法搜尋深度為n,每次都有兩個分支,最終時間複雜度為o(2^n)

2.記憶化搜尋

觀察遞迴搜尋樹可以發現有重複搜尋的地方,加入dp陣列儲存中間結果(剪枝)。

1

int dp[max_n+1][max_w+1]; //

記憶化陣列 23

//i:物品下標 val:當前揹包剩餘容量 返回最大總價值

4int rec( int i, int

val )510

11if( i>=n )

12

1516

int res = 0;17

if( w[i]>val )

18

21else

22

25return dp[i][val] =res;26}

2728

void

solve()

29

view code

對於相同引數只會被呼叫一次,引數的組合只有 nw 種,且每次函式只有兩次呼叫遞迴,所以時間複雜度下降為o(nw)。這種方法稱為記憶化搜尋。

3.動態規劃

結合搜尋函式和相對應的記憶化陣列:

rec(i,j) = rec( i+1, j )                     jmax( rec(i+1,j), rec(i+1, j-w[ i ] ) + v[i] ) otherwise                     = max( dp[ i+1 ][ j ]  , dp[ i+1 ][ j - w[ i ] ] + v[ i ]  )  otherwise

可以不用寫函式,從初始dp[ n ][ j ] = 0 狀態利用上遞推式將各項值計算出來,用二重迴圈即可解決。

這裡及以下所有dp陣列均為全域性變數,當初始值為0時沒有進行初始化。

1

int dp[max_n+1][max_w+1]; //

dp陣列 23

void

solve()413

else

1417}18

}19 printf("

%d\n

",dp[0][w]); //

rec(0,w)

20 }

view code

這時的dp[ i ][ j ] 可以理解為從第i件物品開始選揹包容量為j的最大總價值。

若將dp[ i ][ j ] 理解為從第0見開始選到第i件且揹包容量為j的最大價值,有第二種遞推式。

1

int dp[max_n+1][max_w+1]; //

dp陣列 23

void

solve()414

else

1518}19

}20 printf("

%d\n

",dp[n][w]);

21 }

view code

利用一維陣列:若我們需要的僅僅是最終結果,觀察到dp[ i+1 ][ j ]僅與其上乙個物品時dp[ i ][ j ]有關,所以可以重複利用一維陣列完成遞推式。

1

int dp[max_w+1]; //

一維dp陣列 23

void

solve()411

}12 printf("

%d\n

",dp[w]);

13 }

view code

這時原來的dp[i]的i可以認為是上一次迴圈時產生的dp值,即這一維在i迴圈種被隱去了。 (我也還沒十分了解)

二、完全揹包問題

動態規劃 揹包問題

給定n個物品,重量是,價值是,包的容量 承重 是w 問,放入哪些物品能使得包內價值最大 1 需要將問題轉化為子問題,通過遞迴實現,且子問題必然與父問題存在關聯 2 定義v i,j 表示為,當item取自前i個items且揹包capacity j 時,揹包問題的最優解,也即最高的價值。3 從前i個it...

動態規劃 揹包問題

不廢話,直接上 動態規劃,揹包問題。輸入為 int n 物品的種類數。int n weight 各件物品的重量。int n value 各種物品的價值。int w 揹包最大的裝載重量。輸出 v n b 的值,最大的裝載價值。x n 各類物品的裝載數量。author huangyongye publi...

動態規劃 揹包問題

1 開心的金明 問題描述 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n 元錢就行 今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的n 元。於是,他把每...