背包三讲
来源:互联网 发布:用sql语句查询年龄在 编辑:程序博客网 时间:2024/05/21 10:11
V表示背包容量,v[i]表示物品价值,w[i]表示物品重量,c[i]表示某种物品的个数
1、01背包
for(i=0;i<n;i++)//表示物品总个数 for(j=V;j>=w[i];j--) dp[j] = max(dp[j],dp[j-w[i]] + v[i]);
2、完全背包
for(i=0;i<n;i++)//表示物品总个数 for(j=w[i];j<=V;j++) dp[j] = max(dp[j],dp[j-w[i]] + v[i]);
注意看的话,会发现其实01背包和完全背包只有一行是不一样的。
01背包的二维状态转移方程是dp[i][j] = max(dp[i][j],dp[i-1][j-w[i]] + v[i]),发现第i个状态是由第i-1个状态推出来的,所以第一维可以优化掉,为什么第二重循环是倒着来的呢,因为dp[j] = max(dp[j], dp[j-w[i]] + v[i]),如果正着循环,假设dp[j]由第i-1个状态推出的,那么j正着循环后会变大,那么dp[j+w[i]]就不是由第i-1个状态推出来的,就是由前面算出的第i个状态的dp[j]推出,这样就不是每一个物品只用一次了,很明显就不符合01背包的性质了。
完全背包可以正着循环的原因是完全背包是一种物品有无限多个,正着循环正好可以让一个物品用很多次,这样算出来的就是我们想要的结果。
3、多重背包
for(i=0;i<n;i++)//表示物品的种类{ if(v[i] > V) continue; if(v[i]*w[i]>=V) { for(j=v[i];j<=V;j++) dp[j] = max(dp[j],dp[j-w[i]] + v[i]); continue; } else { int k = 1; while(k < c[i]) { for(j=V;j>=w[i]*k;j--) dp[j] = max(dp[j],dp[j-k*w[i]] + k*v[i]); c[i] -= k; k *= 2; } for(j=V;j>=w[i]*c[i];j--) dp[j] = max(dp[j],dp[j-w[i]*c[i]] + v[i]*c[i]); }}
下面是摘自背包九讲的多重背包的过程,看着应该比较清晰
def MultiplePack(F,C,W,M)
if C M V
CompletePack(F,C,W)
return
k := 1
while k < M
ZeroOnePack(kC,kW)
M := M
解释一下多重背包的过程,如果一个物品的数量乘上他的重量,已经超过了背包的容量,那么就可以当成完全背包来处理;如果没有超过背包的话,可以把拆分成01背包来处理,这里用到了二进制优化,可以大大优化时间复杂度。
0 0
- 背包三讲
- 背包九讲前三讲系列
- 第十三讲
- 第十三讲
- 第十三讲 二次几何体
- 第十三讲习题参考答案
- Oracle Index 三讲
- 第三十三讲 初窥LINQ
- 第十三讲:标签视图
- Java闲言碎语二三讲
- 第二十三讲项目5-
- 第十三讲 绘图(二)
- JavaSE第七十三讲:异常详解
- 第二十三讲:泛型入门
- 第十三讲海量地名效率
- 第⼆⼗三讲:动画
- 第三十三讲|三种循环
- Shader第十三讲 Alpha混合
- async await关键字后面的处理
- 如何使用android studio进行多渠道的打包?
- Bootstrap学习心得
- 【阅读】《黑客与画家》系列01-可测量性与可放大性
- java环境变量的配置
- 背包三讲
- Maven is executing in offline mode. Any artifacts not already in your local repository will be inacc
- (数据类型-字符串)JavaScript权威指南笔记5.1
- app控件唯一相对Xpath自动生成(增强版uiautomatorviewer)
- 【EF】浅谈EF
- webservices输出图像时不能正常显示
- 自定义通知栏,并注册点击事件
- android 底部弹出提示框的实现方式
- C语言sizeof和strlen