2020-10-11《多重背包 单调队列优化》

《多重背包 单调队列优化》
【题目】
有n种物品和一个容量为m的背包。
第i种物品最多有si件,每件体积是vi,价值是wi。
求解选择哪些物品放入背包,使物品体积总和不超过背包容量,且价值总和最大。只输出最大价值。
【输入】
第一行两个整数n和m,分别表示物品种数和背包容量。
接下来有n行,每行三个整数vi,wi,si,分别表示第i种物品的体积、价值和数量。
【输出】
输出一个整数,表示最大价值。
【输入样例】
2 9
3 5 2
2 4 3
【输出样例】
17

1.先从朴素算法入手,跟踪代码,找规律
在这里插入图片描述
我们找到的规律:
在这里插入图片描述
2.增加g数组,把朴素算法改造成顺序更新
在这里插入图片描述
3.接下来,把内层循环替换成单调队列的代码
在这里插入图片描述
接下来逐行解读代码(精华部分)
(1)第14行和16行:把背包容量m(或f[0…m])拆分成v个类,对每个类的元素使用单调队列更新
在这里插入图片描述
(2)第18行:判断何时对头元素出队
在这里插入图片描述
(3)第20行:使用队头最大值更新f
注意: 因为f[k]通过前面的旧值g[q[h]]来更新,所以窗口在g数组上滑动。
在这里插入图片描述
(4)第22行:当前值比队尾值更有价值,队尾出队
在这里插入图片描述
这句代码g[k]>=g[q[t]]+(k-q[t])/v*w与g[k]-(k-j)/vw>=g[q[t]]-(q[t]-j)/v*w
实质是等价的,但这样写代码,意义更简明,形式更优雅,我喜欢!
(5)第24行:下标入队,便于队头出队
这句代码地球人都知道。。。。。

我对代码的解读,你看明白了吗?如果你想更深入透彻地理解算法,请到B站搜索 董晓编程 ,那里有我的视频教程,巴拉巴拉。。。

2020.10.10

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值