IOI论文阅读笔记--动态规划
现仍在更新中...
博客只记录特殊技巧等blablalalal...
背包问题
崔天翼 背包九讲
背包可行性问题
每种有若干件物品能否恰好填满背包。貌似是楼教主“男人八题”。。。
这里代码不是很懂,还在思考
解决了, 此处构造思路如下:
- 定义\(F[i][j]\)为:只利用前i个物品填充枚举体积为j的背包,第i个物品最多剩余个数
- 两个关键循环的思路是这样的:第一个循环判断,前i-1个物品有没有办法完全填充,如果是这样那是最好的情况,那么我肯定直接让这第i个物品闲着
- 第二个循环,考虑在枚举体积允许第i个物品可以“插手”填充背包,也就是说,枚举体积开始可以容下第i个物品的时候,利用递归的思想(就是黑盒子,我的所有子问题统统解决好了),我开始做决定,我必须对第一个循环中被复制为-1的部分有所考虑,因为这一部分还没有引入i物品帮忙,所以第二个循环实质上做的是考虑可以让这第i个物品“插手”解决问题时,我能让i最大剩多少
总结起来,那个关键的循环其实是两步战略
- 第一步,保留我的“嫡系”部队,能让之前“雇佣兵”解决的我先不插手,不能解决对我特殊标记一下
- 第二步,实在没办法了,因为我首先解决问题要紧,这时候,开始考虑可以让我插手但是“雇佣兵”没有解决的部分。
背包混合问题
待代码熟练之后,再吃下这个问题
分组背包问题
这类问题技巧在于多一步:按组分类,而非此前按照物品序号定义状态,在此之后再在当前小组中选择合适的物品。
依赖背包问题
- 对于最简单情形,一个物品只能是依赖于一个,被依赖于一个,单身狗,之中一种,那么对于每一个被"舔"的物品,他的“舔狗”可以组成一个集合,当我们对此“单纯”的集合先01背包处理,我们可以将此集合看作是一个新的物品组,这里已经开始用到泛化物品的思想了,即,对于此集合中,一个费用对应一个最优价值,这一对对应关系我们可以定义出一个物品。在这之后,就已经转化为上一个的分组背包问题了
- 对于复杂的依赖关系是一个“森林”时,就是你的男神/女神是别人的舔狗,我们这里就需要递归地求解,即求每个父亲节点所等价的物品组之前,我们必须递归地利用此DP算法于他的所有子节点,
想想就炸裂
泛化物品问题
文章中还有将前面所有特殊背包问题转化为泛化物品的举例,关键定义在于泛化物品的和,以及将两个泛化物品代替以他们的和,不改变问题的最优答案。
此文阅读暂告一段落,等到熟悉代码时再返回记录心得。
徐持衡 09 浅谈几类背包问题
关于多次背包问题利用单调优先队列优化的问题:
首先给出参考博客:参考
大意复述:
在博客中提到,我们将原先转移方程里的队列比较,转化为另一种队列, 也就是提到的单调优先队列的形式,这种形式有两个好处:
- 表达形式具有通用性,可以看到对于不同的枚举时体积j,基本上只能在当前的j中做操作,而论文中利用余数进行分类的思路,帮我们在不同的j之间可以共享之前维护的成果
- 单调优先队列的构造,序号单调增加,关键值单调减少(或是反过来,看问题)使得我们每次更新完成之后的操作控制时间在O(1)
关键的转移方程:
优化前:\(F[i][j]= max\{F[i-1][j-k*v[i]]+k*w[i]\}, \quad (0<=k<=m[i])\)
优化后:\(F[i][j]= max\{F[i-1][b+k*d]-k*w[i]\}+a*w[i], \quad (a-m[i]<= k<= a)\)
其中:\(m[i]\)为物品i个数, \(v[i]\)为体积,\(j= a*d+b\)
可以看到,优化前的队列\(\{F[i-1][j-k*v[i]]+k*w[i]\}\),只可以在体积为j时访问与使用,而优化后的队列,相当于,数学中的语言来说,分离出一个常用队列\(\{F[i-1][b+k*d]-k*w[i]\}\),使得所有\(modv[i]\)同余的j,都可以使用。
状态压缩
陈丹琦 08 基于连通性状态压缩的动态规划问题
插句闲话,小姐姐真的是好厉害的大牛orz...
状态设计
刘弈 08 浅谈信息学中状态的合理设计与应用
我大胡建真不是盖的。。。为何OI巨佬如此之多,我只是个沫。。。
DP中的好的状态设计往往能起到事半功倍的作用,此文举了三个例子说明。
- 正确分析状态的时间空间复杂度,状态数目以及状态转移效率
- 从一般枚举开始,逐步优化深入
- 优化过程分析冗余项,设定新的状态以除去冗余项并时刻注意复杂度分析
- 可以利用hash方法筛选必要项
优化
毛子青 01 动态规划算法的优化技巧
(福建就是强大的如此低调,脑补摊手手动作)