DP動態規劃之揹包問題 一

2021-10-09 07:32:31 字數 1916 閱讀 7008

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

輸入n=4

(w,v)=w=

5輸出7

#include

using

namespace std;

int*w,

*v;//物品的重量,價值

int n;

//物品的個數

intrec

(int i,

int weight)

//是否選取第i個物品

intmain()

由上述**可知,只要rec函式的引數一樣返回的結果就一樣,可能會出現重複計算的可能

所以引入乙個dp陣列用來儲存已經計算過的rec(前i個物品重量不超過j的最大價值)。

#include

#include

#define max 10

using

namespace std;

int*w,

*v;//物品的重量,價值

int n;

//物品的個數

int dp[max]

[max]

;int

rec(

int i,

int weight)

//是否選取第i個物品

intmain()

根據上面的dp記憶化陣列的定義可知,dp[i][j]表示,從第i個物品開始選取總重量不大於j的物品的價值最大值,它的遞推關係式也可匯出,

所以可以將上面改進過的演算法再作一點改進(雖然演算法複雜度是一樣的,但是會很簡潔)

void

solve()

cout<

[w];

}

最後改進的**是以物品的重量為變數進行動態規劃,但是一旦物品的重量很大,那麼該演算法的複雜度就會大大增加,現在就重量較大,價值較小的問題來進行解決,將dp的物件改為價值。

dp[i+1][j]代表前i個物品價值為j的最小重量,由此可以得到關於dp的遞推關係式:

dp[0]

[0]=

0dp[0]

[j]=inf,不存在這種情況,所以賦予乙個足夠大的值

dp[i+1]

[j]=

min(dp[i]

[j],dp[i]

[j-v[i]

]+w[i]

)/dp[i]

[j]

於是由遞推關係式就可以解決該問題

#include

#define max_v 10

#define max_n 10

#define max 10

#define inf 50

using

namespace std;

int dp[max]

[max_n*max_v]

;int n;

int w;

int*w,

*v;void

solve()

int tmp;

for(

int i=

0;i(dp[n]

[i]<=w)

tmp=i;

cout<

}int

main()

DP 動態規劃 揹包問題

將乙個容量為v的揹包,物品有兩個屬性,乙個w和乙個v表示體積和屬性值。每種物品只有乙個。要求裝下盡可能多,求最大價值。轉移狀態方程 dp j max dp dp j list i w list i v,dp j 1 include includeusing namespace std struct ...

動態規劃(DP)揹包問題

dp做題的步驟 1.確定狀態變數 dp i dp i j 的含義 2.確定狀態轉移方程 3.確定邊界條件 4.確定遞推順序 題目1 01揹包 有n個重量和價值分別為w和v的物品。從這些物品中挑選總重量不超過w的物品。求所有挑選方案中價值總和的最大值 思路 dp i 1 j 表示從前i個物品中選出總重...

DP動態規劃 揹包問題

具體例子 有n個重量和價值分別為wi,vi的物品,從這些物品中挑選出總重量不超過w的物品,求所有挑選方案中價值總和的最大值。例如 n 4 w,v w 5 dp思想 求出狀態轉移方程,也就是求出遞推式。首先將問題一般化 解決此問題需要2個一維陣列,和1個二維陣列 w i 表示第i個物品的重量,下標從0...