揹包問題模板

2021-08-07 17:26:01 字數 2144 閱讀 5246

特點:每種物品只有一件

子問題定義狀態

bag[i][v] : 前i件物品放到乙個容量為v的揹包中可以獲得最大價值

轉移狀態方程

bag[i][v] = max(bag[i-1][v],bag[i-1][v-weight[i]] + value[i])

模板:

#include

#include

using

namespace

std;

int main();//第n件物品的重量

int value[n+1] = ;//第n件物品的價值

//結果最大價值為30

int bag[n+1][v+1];

memset(bag,0,sizeof(bag));//陣列初始化,必須包含標頭檔案

for(int i = 1; i <= n; i++)else }}

cout

0; }

效率分析

以上演算法的時間複雜度為o(n*v),空間複雜度也為o(n*v).其中,n 表示物品個數,v 表示揹包容量這裡,時間複雜度不可以在優化了,但是空間複雜度可以繼續優化到o(v).

空間複雜度優化

關鍵:由二維陣列bag[n][v]改為用一維陣列bag[v]來儲存中間變數。

關鍵**修改:

int bag[v+1];

memset(bag,0,sizeof(bag));

for (int i = 1;i <= n;i++)

}cout

《每種物品的數量為無限

轉移狀態方程修改為:

bag[j] = max(bag[j],bag[j-k*weight[i]]+k*value[i]);

k:列舉能拿幾件

完全揹包主要加了一層迴圈來列舉可以拿走的物品數量count

count = v/weight[i];

原因:原因:假如有揹包容量為6,有一物品重量為1,價值為2。此時根據揹包的重量,最多只能拿6件而已。

模板:#include

#include

using

namespace

std;

int main();//第n件物品的重量

int value[n+1] = ;//第n件物品的價值

//結果最大價值為40

int bag[v+1];

int count;

memset(bag,0,sizeof(bag));//陣列初始化,必須包含標頭檔案

for(int i = 1; i <= n; i++)}}

cout

0; }

特點:每種物品的數量有上限

轉移狀態方程與完全揹包相同:

bag[j] = max(bag[j],bag[j-k*weight[i]]+k*value[i]);

主要就是列舉數量count的取值變為

count = min(num[i],v/weight[i]);

原因:假如有揹包容量為6,有一物品重量為1,價值為2,數量為10。雖然該物品有10件,但你的揹包容量最多隻允許你拿6件而已。

模板:

#include

#include

using

namespace

std;

int main();//第n件物品的重量

int value[n+1] = ;//第n件物品的價值

int num[n+1] = ;//第n件物品的上限數量

//結果最大價值為64

int bag[v+1];

int count;

memset(bag,0,sizeof(bag));//陣列初始化,必須包含標頭檔案

for(int i = 1; i <= n; i++)}}

return

0; }

揹包問題模板

01揹包在時間複雜度上都是n n v 在這個基礎之上已經不能再進行優化了,在空間複雜度上,我們首先看一下複雜度為o n v 的程式 for int i 1 i n i for int j 0 j w j 但是我們還可以將空間複雜度壓縮為o v 我們會發現這裡每次更新第i層都只是看第i 1層,其他層的...

模板 揹包問題

include include define max a,b a b a b using namespace std const int n 1005 int n,v,v n w n int dp n voidf intmain f printf d n dp v return0 include i...

揹包問題模板

有n種物品和乙個容量為v的揹包。第 i 件物品的體積是 c i 價值是 w i 由於每種物品有且僅有一件,因此只能選擇放或不放,我們稱之為 01 揹包問題。現在你需要選出若干件物品,在它們的重量之和不超過 v 的情況下,使總價值盡可能達到最大。for int i 1 i n i else 優化空間複...