揹包問題總結(模板)

2021-08-10 02:17:38 字數 1488 閱讀 5951

01揹包:

有n個物品,每個物品對應的價值和體積,且每個物品只能選一次,揹包體積為v求揹包所能裝物品的最大價值

#include#includeconst int maxn=10002;//n表示物品個數 

int f[maxn],v[maxn],val[maxn],v,n;//v表示揹包體積

using namespace std;//v表示物品的體積,

int main()//val表示物品的價值

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

for(int j=v;j>=v[i];j--)

f[j]=max(f[j],f[j-v[i]]+val[i]);

printf("%d",f[v]);

return 0;

}

完全揹包:

和01揹包基本類似,不同的只是每種物品可以取無數次;

對於完全揹包的一維遞推方程,我們只需要更改一下迴圈方向即可

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

for(int j=v[i];j<=v;j++)

f[j]=max(f[j],f[j-v[i]]+val[i]);//完全揹包**核心;

多重揹包:

對於每一件物品我們對其規定件數(最多能使用多少件),我們可以對於每一種物品,列舉其件數,對於每一件物品,我們對其的狀態只有兩種:拿,不拿;所以我們可以轉化成為01揹包來求解

//第一層我們列舉物品種類

//第二層我們列舉揹包體積;

//第三層我們列舉每種物品的個數

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

for(int j=v;j>=0;j--)

for(int k=0;k<=c[i];k++)

if(k*v[i]>j) break;//注意特判

else f[j]=max(f[j],f[j-k*v[i]]+k*val[i]);

printf("%d",f[v]);

分組揹包:

我們來看一下什麼是分組揹包?

有n件物品和乙個容量為v的揹包,對於每一件物品給出該物品的體積價值和組別,由於每組的物品之間相互衝突,所以對於每組物品我們最多選擇一件,求解將哪些物品裝入揹包可使體積總和不超過揹包容量且價值最大;

也就是說我們可以從分組的角度來看,這其實是乙個01揹包問題,選或不選乙個組的某乙個物品:

對於分組揹包我向大家推薦一種儲存方式,這種方式讓**簡潔易懂

我們在儲存組數的時候可以開乙個二維陣列a,用a[i][0]來表示組別為i的物品的個數;

然後用a[i][j]來表示組別為i的第幾的物品,

附上偽**:

for k=所有的組數

for v=v...0;

for 所有的i屬於k組的

f[v]=max(f[v],f[v-v[a[k][i]]]+val[a[k][i]]])

大家可以好好體會一下a這個二維陣列的巧妙。

ACM模板 揹包問題模板總結

揹包問題模板 一維陣列 滾動陣列 模板 for int i 1 i m i 例題一維陣列 滾動陣列 模板 for int i 1 i m i 例題模板 以兩個附件為例 for int i 1 i m i if j good i 0 v good i 1 v if j good i 0 v good ...

揹包問題模板

特點 每種物品只有一件 子問題定義狀態 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 i...

揹包問題模板

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層,其他層的...