算法解析之感想---单调队列优化多重背包思路
来源:互联网 发布:什么是网络代理 编辑:程序博客网 时间:2024/05/24 04:52
多重背包问题朴素时间复杂度为O(NMS)(这里S是所有物品的数量s之和),经过二进制优化后时间复杂度为O(NMlog2S),这个复杂度已经能够应付大多数题了,但对于某些特别卡时间的题(比如N*M=10的7次方),仍然会TLE。这时,可以用单调队列优化,时间复杂度降为O(NM)。其优化思路是将当前重量限制取余物品重量数得到余数相同的归为一类,因此可以分为[0,V[i]-1]供V[i]类,其中对于每一类可以用单调队列优化,此时均摊分析时复杂度为O(M)。
首先看一下多重背包问题的朴素转移方程:
F[i][j] = max{F[i-1][j-x*w[i]]+x*v[i]} (0<=x<=s[i], j>=x*w[i])
如果使用滚动数组,忽略i这一维,设w0=w[i](重量),v0=v[i](价值),s0=s[i](数量),得:F[j] = max{F[j-x*w0]+x*v0} (0<=x<=s0, j>=x*w0)
看上去这和单调队列木有神马关系,因为决策下标(j-x*w0)不是一个整数区间,中间是有间隔的。然而可以发现,这个方程的限制条件“0<=x<=s0,j>=x*w0”,也就是x的下界是max{0, j/w0(下取整)}(即只有当x取这里面的数的时候可以实现在最多有x个物品的限制下状态正确转移),当j单调递增时,这个下界也是单调递增的。这满足单调队列优化的条件中的“决策下标的下界单调”……不是,还不能这样说,因为这里的决策下标是j-x*w0,而不是x。那么怎样才可以把决策下标变为x?
然后,转移方程可以改为(这里把r当成一个已知量了):F[q*w0+r] = max{F[k*w0+r]+(q-k)*v0}(q-k:买了q-k个) (k>=0且q-s0<=k<=q)
即F[q*w0+r]=max{F[k*w0+r]-k*v0}+q*v0 (k>=0且q-s0<=k<=q)
设G[k]=F[k*w0+r]得:
G[q]=max{G[k]-k*v0}+q*v0 (k>=0且q-s0<=k<=q)
首先看一下多重背包问题的朴素转移方程:
F[i][j] = max{F[i-1][j-x*w[i]]+x*v[i]} (0<=x<=s[i], j>=x*w[i])
如果使用滚动数组,忽略i这一维,设w0=w[i](重量),v0=v[i](价值),s0=s[i](数量),得:F[j] = max{F[j-x*w0]+x*v0} (0<=x<=s0, j>=x*w0)
看上去这和单调队列木有神马关系,因为决策下标(j-x*w0)不是一个整数区间,中间是有间隔的。然而可以发现,这个方程的限制条件“0<=x<=s0,j>=x*w0”,也就是x的下界是max{0, j/w0(下取整)}(即只有当x取这里面的数的时候可以实现在最多有x个物品的限制下状态正确转移),当j单调递增时,这个下界也是单调递增的。这满足单调队列优化的条件中的“决策下标的下界单调”……不是,还不能这样说,因为这里的决策下标是j-x*w0,而不是x。那么怎样才可以把决策下标变为x?
然后,转移方程可以改为(这里把r当成一个已知量了):F[q*w0+r] = max{F[k*w0+r]+(q-k)*v0}(q-k:买了q-k个) (k>=0且q-s0<=k<=q)
即F[q*w0+r]=max{F[k*w0+r]-k*v0}+q*v0 (k>=0且q-s0<=k<=q)
设G[k]=F[k*w0+r]得:
G[q]=max{G[k]-k*v0}+q*v0 (k>=0且q-s0<=k<=q)
这个方程已经可以使用单调队列来优化了!
参考文献:
1.《背包九讲》
2.http://www.cppblog.com/MatoNo1/archive/2011/07/05/150231.html(主题思路)
3.http://wenku.baidu.com/view/8ab3daef5ef7ba0d4a733b25.html(国家集训队2009论文集浅谈几类背包题)
- 算法解析之感想---单调队列优化多重背包思路
- 多重背包单调队列优化
- 单调队列优化多重背包
- 单调队列优化多重背包
- 单调队列优化多重背包
- 多重背包的优化 二进制/单调队列解析
- 多重背包O(VN)算法——单调队列优化
- 多重背包,二进制优化,单调队列优化
- hdu2191多重背包单调队列优化
- Dividing(多重背包、单调队列优化dp)
- 多重背包(单调队列优化)
- poj1742 单调队列优化多重背包
- 单调队列优化的多重背包
- 多重背包(单调队列优化)
- poj1014多重背包--单调队列优化
- hdu1171 (单调队列优化多重背包)
- 多重背包的单调队列优化
- 多重背包中多次背包 O(VN) 算法1 (单调队列优化) 带参考程序
- CentOS5关机出现sh-3.2#与shutdown命令用法
- 怎样在JSTL标签中获得集合的长度
- ubuntu12.04修改终端ls颜色
- 十道海量数据处理面试题与十个方法大总结
- 将编译AS3区分Debug版本和Release版本
- 算法解析之感想---单调队列优化多重背包思路
- 黑马程序员_面向对象的程序设计
- Jquery练习题
- 理解synchronized对象锁
- python中简单的读写文件操作
- ubuntu 软件安装管理
- 二分查找法的实现和应用汇总
- 在VS2010,VC6.0中使用SkinMagicToolkit的不同比较
- 微软编程之美2013全国挑战赛 资格赛 第1题