有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...