完全揹包
完全揹包與01揹包的區別在於,01揹包中所有物品要麼選要不不選,完全揹包是所有物品可以選任意次。完全揹包與01揹包很相似,可以將完全揹包轉換成01揹包,也可以找到其狀態轉移方程。
問題描述:
有n件物品和一個容量爲C的揹包,每件物品都有無限件可用,第i件物品的體積爲w[i],價值是v[i],求解將哪些物品放入揹包可使這些物品的價值總和最大並且不超過揹包容量。
算法分析:
與01揹包對比一下,看到的區別是,完全揹包問題中,物品有無限多件。往揹包裏面添加物品時,只要當前揹包沒裝滿,可以一直添加。那麼狀態轉移方程爲:
f[i+1][j]=max(f[i][j-kw[i+1]]+kv[i+1]),其中0<=k<=C/w[i+1]
使用內存爲一維數組,僞代碼
for i=1……N
for j=w[i]……C
f[j]=max(f[j],f[j-w[i]+v[i])
和01揹包問題唯一不同的是j是從1到C。01揹包問題是在前一個子問題(i-1種物品)的基礎上來解決當前問題(i種物品),向i-1種物品時的揹包添加第i種物品;而完全揹包問題是在解決當前問題(i種物品),向i種物品時的揹包添加第i種物品。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=2e2+10;
int f[N],w[40],v[40],n,C;
int main()
{
//fre();
scanf("%d%d",&C,&n);
for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&v[i]);
for(int i=1;i<=n;i++)
for(int j=w[i];j<=C;j++)
if(w[i]<=j) f[j]=max(f[j],f[j-w[i]]+v[i]);
printf("max=%d",f[C]);
return 0;
}
其他揹包問題:
揹包問題(1)-01揹包