完全背包
完全背包问题是在01背包问题上进行扩展:一件物品不仅可以取0,或1次,还可以取2,3…次,没有限制,求解在背包总体为V 的情况下所获得的物品的最大价值。
图示:
会发现分析思路和0背包问题类似,如果还没有了解01背包问题,可以看我的这篇01背包详解:01背包问题详解这时写出的的代码应该是一个三重循环,因为还要枚举K的个数,因此我们要想办法优化掉一维,及使得状态转移方程和k无关:
由此得到新的状态转移方程:
f[i,j]=Max(f[i-1,j],f[i,j-v]+w[i]
最后我们可以将f像在01背包问题中分析的那样,给他去掉一维,并且由于这个f[i,j-v]+w就是在第i层的,所以我们不需要将j从m开始倒转。
完整代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m,v[N],w[N],f[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&v[i],&w[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=v[i];j<=m;j++)
{
//f[i][j]=max(f[i-1][j],f[i][j-v[i]]+w[i])
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[m]<<endl;
return 0;
}