动态规划9_完全背包

最后是完全背包(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种背包时所得的价值,
这里我们要添加的不是前一个背包,而是当前背包。所以我们要考虑的当然是当前状态。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值