最后是完全背包(CompletePack),
问题:有N种物品和一个容量为V的背包,每件物品都有无限件可用,每件的费用是w[i],价值是v[i]。
将物品放入背包中,使得总容量不超过V,而且总价值最大。
从0-1背包的思想可以得出状态转移方程:
dp[i][j]=max(dp[i-1][j-k*w[i]]+k*v[i]|0<=k*w[i]<=j)
代码实现:
void solve()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<=W;j++)
{
for(int k=0;k*w[i]<=j;k++)
{
dp[i+1][j]=max(dp[i+1][j],dp[i][j-k*w[i]]+k*v[i]);
}
}
}
printf("%d\n",dp[n][W]);
}
上面的空间复杂度是O(n*W)时间复杂度是
O(n*W^2)
其实还可以将空间优化成O(W),时间优化成O(n*W)。
void solve()
{
for(int i=0;i<n;i++)
{
for(int j=w[i];j<=W;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
printf("%d\n",dp[W]);
}
第二个循环顺序的原因:
因为每种背包都是无限的。当我们把i从1到N循环时,f[v]表示容量为v在前i种背包时所得的价值,
这里我们要添加的不是前一个背包,而是当前背包。所以我们要考虑的当然是当前状态。