单调队列优化的多重背包
来源:互联网 发布:函数编程题的心得体会 编辑:程序博客网 时间:2024/05/16 15:32
单调队列优化的多重背包
Decription
给定N种物品和一个容量为M的背包,每种物品都有三个属性:价值
目标:选择若干个物品装入背包,使其容量和不超过M,并最大化价值和
Solution 1
设
状态转移方程如下:
直接枚举
Solution2
观察方程
为了方便看,我们令
于是得到
接下来是最关键的一步
似乎没什么头绪,但我们发现一个性质,就是
于是我们就把每一组“抖”出来,单独研究它 的转移。比如我们只研究{2,5,8,11,…}这一组,其通项公式为
这样枚举a的话,实际上决策区间就是连续的了,那么问题就变成动态维护最大值,显然用单调队列就好了(单调队列不再啰嗦,感兴趣者可以去看我的sliding window那篇文章)。
这里有个小问题,当我们的a增加1的时候,原来的
综上,时间复杂度优化到
Problems
hdu 2191,不加优化就能过
CodeVS 5429,必须用单调队列优化(题目卡log)
Code
这是hdu2191
//多重背包 单调队列优化 #include <cstdio>#include <algorithm>#include <cstring>#define maxn 1100#define maxm 1100using namespace std;int N, M, p[maxn], h[maxn], c[maxn], qw[maxm], qn[maxm], f[maxn][maxm];void input(){ int i, j; scanf("%d%d",&M,&N); for(i=1;i<=N;i++)scanf("%d%d%d",p+i,h+i,c+i);}void dp(int *f, int *g, int prize, int height, int c){ int l=1, r=1, d=0, k, a, b, mini; for(b=0;b<prize;b++) { l=1,r=1,qw[r]=g[b],qn[r++]=b; for(a=0,d=0;a+b<=M;a+=prize,d+=height) { while(qw[r-1]+d<=g[a+b] and l<r)r--; qw[r]=g[a+b]-d,qn[r++]=a+b; mini=max(0,a+b-prize*c); while(qn[l]<mini)l++; f[a+b]=qw[l]+d; } }}int main(){ int C, i, j; scanf("%d",&C); while(C--) { input(); for(i=1;i<=N;i++)dp(f[i],f[i-1],p[i],h[i],c[i]); printf("%d\n",f[N][M]); } return 0;}
这是CodeVS 5429
#include <cstdio>#include <algorithm>#include <cstring>#define maxn 7010#define maxm 7010using namespace std;int N, M, p[maxn], h[maxn], c[maxn], qw[maxm], qn[maxm], f[2][maxm];void input(){ int i, j; scanf("%d%d",&N,&M); for(i=1;i<=N;i++)scanf("%d%d%d",p+i,h+i,c+i);}void dp(int *f, int *g, int prize, int height, int c){ int l=1, r=1, d=0, k, a, b, mini; for(b=0;b<prize;b++) { l=1,r=1,qw[r]=g[b],qn[r++]=b; for(a=0,d=0;a+b<=M;a+=prize,d+=height) { while(qw[r-1]+d<=g[a+b] and l<r)r--; qw[r]=g[a+b]-d,qn[r++]=a+b; mini=max(0,a+b-prize*c); while(qn[l]<mini)l++; f[a+b]=qw[l]+d; } }}int main(){ int i, j; input(); for(i=1;i<=N;i++)dp(f[i&1],f[~i&1],p[i],h[i],c[i]); printf("%d\n",f[N&1][M]); return 0;}
0 0
- 单调队列优化的多重背包
- 多重背包的单调队列优化
- 多重背包单调队列优化
- 单调队列优化多重背包
- 单调队列优化多重背包
- 单调队列优化多重背包
- 多重背包,二进制优化,单调队列优化
- 多重背包问题的单调队列优化 转载
- hdu 2191 (多重背包的单调队列优化)
- 动态规划的单调队列优化(含多重背包)
- 多重背包的优化 二进制/单调队列解析
- hdu2191多重背包单调队列优化
- Dividing(多重背包、单调队列优化dp)
- 多重背包(单调队列优化)
- poj1742 单调队列优化多重背包
- 多重背包(单调队列优化)
- poj1014多重背包--单调队列优化
- hdu1171 (单调队列优化多重背包)
- StringBuffer学习笔记
- SSM框架——使用MyBatis Generator自动创建代码
- 【codeforces 727 A】【dfs或者逆向思维】【给你两个操作,问能不能把数字a变成b】
- 运维开发融合
- 动动乐公司笔试
- 单调队列优化的多重背包
- Matlab 小程序 yuv图片融合
- 剔除单向链表重复值节点时的烦人bug
- POJ3169Layout(线性约束)
- java中冒泡排序与选择排序的区别
- 2013_hangzhou_online
- Markdown语法学习
- 复制表和删除表
- 细说Android框架设计三剑客MVC、MVP和MVVM