【DP】完全背包

算法-


前置知识

思路

完全背包一般分为两种,不妨叫做价值完全背包和判断完全背包。

价值完全背包

完全背包问题是这样的一类问题:给定一个背包的容量 m m m n n n 种物品,每种物品有重量 w w w 和价值 v v v,并且可以购买装无限个,求不超过背包容量时可以装下的最大价值。
对于这类问题,我们使用DP,设 f i , j f_{i,j} fi,j 为考虑前 i i i 种物品时总重恰好为 j j j 的最大价值和。
容易得到DP方程: f i , j = max ⁡ k = 0 f i − 1 , j − k w + k v f_{i,j}=\max\limits^{}_{k=0}f_{i-1,j-kw}+kv fi,j=k=0maxfi1,jkw+kv

判断完全背包

思路类似,方程变为 f i , j = f i − 1 , j ∣ f i − 1 , j − w + v f_{i,j}=f_{i-1,j}\mid f_{i-1,j-w}+v fi,j=fi1,jfi1,jw+v 即可


算法参数
  • 时间复杂度: O ( n m ) O(nm) O(nm)
  • 空间复杂度: O ( n m ) O(nm) O(nm)

滚动优化

完全背包的滚动优化与01背包不太一样。
01背包继承的状态没有被更新,所以要倒着来,但是完全背包我们完全可以这样看: f i , j = max ⁡ ( f i , j , f i , j − w ) f_{i,j}=\max(f_{i,j},f_{i,j-w}) fi,j=max(fi,j,fi,jw)
也就是说,我们只需要正着循环就可以了。(此处建议手动模拟一下)


实现代码
  • 价值
f[0]=0;
for (int i=1;i<=n;i++)
	for (int j=w[i];j<=m;j--)
		f[j]=max(f[j],f[j-w[i]]+v[i]);
  • 判断
f[0]=1;
for (int i=1;i<=n;i++)
	for (int j=w[i];j<=m;j--)
		f[j]=f[j]|f[j-w[i]];

练习
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值