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