多重背包单调队列优化思路_单调队列优化多重背包问题
题目链接:
6. 多重背包问题 III - AcWing题库www.acwing.com背包九讲bilibiliwww.bilibili.com
闫学灿大神的背包九讲到两种完全背包问题的优化算法,第一种是通过二进制拆包将时间复杂度从N*S*M降低到N*logS*M。第二种是通过单调队列将算法的时间复杂度进一步降到N*M。不过视频讲解太快,思路没跟上来。核心代码就四五行,但是没有理解思路的话是很难看懂的,我花了一天时间才算看明白。网络上找到的资料要么排版太差,要么就是符号不一致,看起来很费力,所以干脆自己整理一份资料。
设N表示有多少种物品,C[i]记录每种物品的容量,W[i]记录每种物品的价值,S[i]记录每种最多能放多少个,M表示背包的容量。如果是一路看大雪菜视频过来的话,很容易得到状态转移方程:
从公式中可以看出f[j]和f[j+c]都是从s+1个数里面取最大值,计算f[j+c]时只是将滑动窗口右移了一步,类似下图的效果:
只不过移动的时候,前面的s个元素都增加了w,每个元素加上相同的数不影响计算最大值。使用单调队列可以在O(N)时间复杂度下找到所有滑动窗口的最大值,关于单调队列处理滑动窗口的问题可以看看这篇文章:
labuladong:特殊数据结构:单调队列zhuanlan.zhihu.com
容易知道f[j]的计算只依赖于g[k],其中j%c = k%c。因此可以将g[0~m]按%c的余数进行分类:
g[0],g[c],g[2c],g[3c],...
g[1],g[1+c],g[1+2c],g[1+3c],...
...
g[c-1],g[2c-1],g[3c-1],g[4c-1]...
每个分类可以计算出:
f[0],f[c],f[2c],f[3c],...
f[1],f[1+c],f[1+2c],f[1+3c],...
...
f[c-1],f[2c-1],f[3c-1],f[4c-1]...
从而整个f[0~m]都能计算出来。
上面的讲解可能有点啰嗦,归纳起来就两点:
- 需要将所有状态按照%c的余数进行分类,每个分类可以计算出下一层对应的分类
- 计算下一层对应分类的过程类似于滑动窗口取最大值,利用单调队列可以实现O(N)的时间复杂度
综上所述,C++代码如下:
#include <iostream>
#include <deque>
#include <vector>
#include <algorithm>using namespace std;int main() {int n, m;cin >> n >> m;deque<int> q;vector<int> f(m + 1), g(m + 1);for (int i = 0; i < n; ++i) {int c, w, s;cin >> c >> w >> s;swap(f, g);for (int j = 0; j < c; ++j) {q.clear();for (int k = j; k <= m; k += c) {f[k] = g[k];if (!q.empty() && k - s * c > q.front()) q.pop_front(); // 最多s+1个元素,超出个数限制则移除队首元素if (!q.empty()) f[k] = max(f[k], g[q.front()] + (k - q.front()) / c * w); // 队首肯定是最大的while (!q.empty() && g[q.back()] + (k - q.back()) / c * w <= g[k]) q.pop_back(); //将k压入队列前,先把所有比它小的出队q.push_back(k);}}}cout << f[m] << endl;return 0;
}
遗憾的是居然超时了。。。。。主要是因为deque.clear()太频繁了,每次clear都会清空内存,也不存在lazy clear的API。没办法只能用数组模拟队列了。最终提交通过的代码如下:
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;int main() {int n, m;cin >> n >> m;int q[20010];vector<int> f(m + 1), g(m + 1);for (int i = 0; i < n; ++i) {int c, w, s;cin >> c >> w >> s;swap(f, g);for (int j = 0; j < c; ++j) {int hh = 0, tt = -1;for (int k = j; k <= m; k += c) {f[k] = g[k];if (hh <= tt && k - s * c > q[hh]) ++hh; // 最多s+1个元素,超出个数限制则移除队首元素if (hh <= tt) f[k] = max(f[k], g[q[hh]] + (k - q[hh]) / c * w); // 队首肯定是最大的while (hh <= tt && g[q[tt]] + (k - q[tt]) / c * w <= g[k]) --tt; //将k压入队列前,先把所有比它小的出队q[++tt] = k;}}}cout << f[m] << endl;return 0;
}
说实话,这种第一次不照着答案敲是很难写对的,不过思路明白了下次写就容易很多了。
多重背包单调队列优化思路_单调队列优化多重背包问题相关推荐
- 多重背包单调队列优化思路_动态规划入门——多重背包与单调优化
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...
- 多重背包单调队列优化思路_多重背包之单调队列优化理论性总结
多重背包之单调队列优化: 若用F[j]表示对容量为j的背包,处理完前i种物品后,背包内物品可达到的最大总价值,并记m = min(n, j / v).放入背包的第i种物品的数目可以是:0.1.2--, ...
- 多重背包单调队列优化思路_多重背包问题
题目描述: 无优化版本: int main(){int m, n;cin >> n >> m;for(int i = 1; i <= n; ++i){int v , w, ...
- sql并发 锁 优化思路_并发优化–减少锁粒度
sql并发 锁 优化思路 在高负载多线程应用程序中,性能非常重要. 开发人员必须意识到并发问题才能获得更好的性能. 当我们需要并发时,我们通常拥有必须由两个或更多线程共享的资源. 在这种情况下,我们处 ...
- oracle 10g 速度慢,让Oracle跑得更快—Oracle 10g性能分析与优化思路_数据库教程
资源名称:让Oracle跑得更快-Oracle 10g性能分析与优化思路 内容简介: 在这本书里读者将会学到作者在性能优化方面的一些思路和思考,一些故障处理的方法和原则,这些东西是作者在实践中长期积累 ...
- sql优化的方法及思路_微生物发酵 技术优化思路 与方法
发酵是细胞大规模培养技术中最早被人们认识和利用的.发酵技术在医药.轻工.食品.农业.环保等领域的广泛应用,使这一技术在国民经济发展中发挥着越来越重要的作用. 为了提高发酵生产水平,人们首先考虑的是菌种 ...
- 飞浆AI studio人工智能课程学习(2)-Prompt优化思路|十个技巧高效优化Prompt|迭代法|Trick法|通用法|工具辅助
文章目录 优化思路 上节课的例子 问题分析 思路解析 Prompt优化技巧 Prompt优化原理 十个技巧高效优化Prompt 迭代法 Trick法 工具法 通用技巧│定基础 通用技巧│做强调 需求强 ...
- 优化 回归_使用回归优化产品价格
优化 回归 应用数据科学 (Applied data science) Price and quantity are two fundamental measures that determine t ...
- python网页优化公司_使用python优化scipy.optimize.minimize公司
我将逐行检查您的代码,并强调一些问题:from scipy.optimize import minimize import numpy as np prices=np.array([[1.5,50,3 ...
- 奇奇seo优化软件_信阳seo优化排名软件
信阳seope4c65优化排名软件,5g时代的到来,使得很多企业对移动互联网的推广预算再次增加.究其原因,是移动互联网用户数量的增加,使得行业竞争对手增多,网络推广成本提高.如果预算不增加,企业网站的 ...
最新文章
- 在数组中查找一个数并输出所处位置
- Latex合并及插入图片相关问题
- 用私有构造器或者枚举类型强化Singleton 属性
- SSY and JLBD
- PHP 获取JSON json_decode返回NULL解决办法
- python图片保存重命名_Python实现重命名一个文件夹下的图片
- JeecgBoot 单表数据导出多sheet实例
- PTA-6-1 数组循环右移 (20分)(C语言)
- Sysbench压测
- Bezier(贝塞尔)曲线(五阶)的轨迹规划在自动驾驶中的应用(五)
- vue-cli 中stylus写样式莫名报错?
- 中文文本纠错算法实现
- 硕士转行学python_0基础转行编程学习Python是最快的途径吗?
- Linux与网络服务(零)从零开始聊聊Linux相关概念(科普向)
- 高斯函数及高斯滤波器
- iwconfig使用
- python爬取搜狗微信的推文
- DAPP 开发直通车-如何基于NEL 轻钱包来开发DAPP
- RabbitMQ3.10.7高级特性
- python读取中文txt乱码问题
热门文章
- pcl学习之kd-tree
- Focal Loss for Dense Object Detection解读
- layui,返回的数据不符合规范,正确的成功状态码 (code) 应为:0
- Vue生命周期-手动挂载理解
- 为什么RegisterClientScriptResource方法在自定义控件中的RenderContents期间不起作用?...
- 【OpenCV学习笔记】【编程实例】三(将一个图像中的指定区域拷贝到另一个图像的指定区域
- 【pytorch】(断点)继续上次训练
- 设置MySQL最大连接数
- android实现Materia Design风格APP(三):部分Materia Design风格的控件介绍二
- 四阶龙格库塔法的基本思想_“李军班长工作法”为“卓越班组”建设注入新动力...