特點:每種物品只有一件
子問題定義狀態
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 優化空間複...