在hihocoder上面的題目中看到的這個問題,總結一下。先看01揹包問題。
01揹包問題:乙個揹包總容量為v,現在有n個物品,第i個 物品體積為weight[i],價值為value[i],現在往揹包裡面裝東西,怎麼裝能使揹包的內物品價值最大?
看到這個問題,可能會想到貪心演算法,但是貪心其實是不對的。例如最少硬幣找零問題,要用動態規劃。動態規劃思想就是解決子問題並記錄子問題的解,這樣就不用重複解決子問題了。
動態規劃先找出子問題,我們可以這樣考慮:在物品比較少,揹包容量比較小時怎麼解決?用乙個陣列f[i][j]表示,在只有i個物品,容量為j的情況下揹包問題的最優解,那麼當物品種類變大為i+1時,最優解是什麼?第i+1個物品可以選擇放進揹包或者不放進揹包(這也就是0和1),假設放進揹包(前提是放得下),那麼f[i+1][j]=f[i][j-weight[i+1]+value[i+1];如果不放進揹包,那麼f[i+1][j]=f[i][j]。
這就得出了狀態轉移方程:
f[i+1][j]=max(f[i][j],f[i][j-weight[i+1]+value[i+1])。
可以寫出**測試:
[cpp] view plaincopy在code上檢視**片派生到我的**片
#includeusing namespace std;
#define v 1500
unsigned int f[10][v];//全域性變數,自動初始化為0
unsigned int weight[10];
unsigned int value[10];
#define max(x,y) (x)>(y)?(x):(y)
int main()
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
else
f[i][j]=f[i-1][j];
} cout#define v 1500
unsigned int f[v];//全域性變數,自動初始化為0
unsigned int weight[10];
unsigned int value[10];
#define max(x,y) (x)>(y)?(x):(y)
int main()
for (int i=1; i<=n; i++)
for (int j=m; j>=1; j--)
} cout#define v 1500
unsigned int f[v];//全域性變數,自動初始化為0
unsigned int weight[10];
unsigned int value[10];
#define max(x,y) (x)>(y)?(x):(y)
int main()
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
} cout<}
0 1揹包和完全揹包
一.0 1揹包 1.0 1揹包指的是每件物品要麼取一次,要麼不取,目的是找到裝到揹包裡最大價值。c n 代表物體重量,w n 代表物體價值,v代表揹包容量。2.時間複雜度 o n v n指的是物品個數,v指的是揹包的容量,這是最優情況,無法再優。3.空間複雜度 原始 f n 1 v 1 改進 f v...
01揹包,完全揹包
動態規劃 動態規劃的核心是狀態以及狀態轉移方程。需要定義乙個 i,j 狀態以及該狀態的指標函式d i,j 01揹包 有n種物品,每種只有乙個,第i件物品的體積為vi質量為wi。選一些物品裝到體積為c的揹包中,使其體積不超過c的前提下重量最大。namevw abcd e 子問題定義 dp i j 表示...
01揹包 完全揹包
本文主要使用一維陣列進行使用 意思 01揹包 代表物品只有兩種狀態,只能使用一次。如,dp i max dp i dp i wight j value j 代表容量為i所獲得的最大利潤。完全揹包 乙個物品可以使用無限次 技巧 1.如果是0 1揹包,即陣列中的元素不可重複使用,nums放在外迴圈,ta...