1.背包问题
01背包问题
转移方程为
转移条件为
这是最裸的动态规划问题之一,从这个问题可以扩展出很多新问题来
可以用滚动数组将空间复杂度优化至 O(n)
完全背包问题
在01背包的基础上多出来每个物品可以选择多次的条件
转移方程为
转移条件为
与01背包并没有很大的区别
多重背包问题
与完全背包不同的是,物品可以多次选择但有次数限制
所以直接在完全背包的转移条件上加上即可
混合背包问题
将上述3种背包混合在一起
还是没有什么区别,只需转移时对物品分类讨论即可
条件背包问题
部分物品需要在满足其它物品的限制下才能使用
对于这种问题,记忆化搜索要比直接计算方便得多
方程其实还是没有什么变化,但在转移时要对条件进行相应的修改,同时也要考虑边界情况
2.树形动规
理论上这一节应该放在树论的部分,但在这里我们还是提一下。
因为树有很强的递归结构,我们可以考虑以同样的方式进行状态转移
对于大多数的树形动规问题,我们可以在遍历时求出其dp值
在处理完子树后将子树对当前节点的答案的贡献求出即可
3.区间动规
一般的区间动规解法大多相同:
先枚举区间的长度,然后从头到尾枚举每个区间
这样的话可以保证每个前驱状态已被算到,这两步的复杂度是
O(nlgn)的
转移的时候要注意边界情况,即区间中只剩下一个元素时的处理方法
4.状压动规
在某些情况下部分元素的个数极少,这时候可以考虑指数级算法。
我们用一个二进制数表示集合中每个元素的状态,于是二进制的或就可以表示集合的并,且就表示集合的交,判断一个元素是否存在只需要判断该元素所对应的位置是否为1。然后在dp时枚举每个子集并进行状态转移,就差不多了。
5.数位动规
数位动规一般是进行一些对于数字本身的统计。对于这种问题的通用思想是一次单独考虑一种数字对答案的贡献,然后利用乘法原理来合并相同的问题。还有一些小技巧,对于一些问题可以考虑补齐一个数的前导零,这样在处理时更方便
6.动态规划的优化问题
决策单调性
对于某些动态规划问题,越靠前的状态转移的决策越好,那么就可以使用单调队列优化,单调队列可以保证存在于队列中的元素的dp值得单调性,在求当前状态的dp值时只需弹出队尾的元素直到满足转移条件。计算完后再将其插入队列中,并弹出不满足单调性的决策。
斜率优化
我们将一些状态转移方程写出来,如果i是由j转移的,那么j就比k要优,在同时满足决策单调性的情况下那么k就是不必要的状态。利用合适的方法把一种决策抽象到平面上的点,那么有可能成为决策的点会在一个凸壳上,于是在转移时在凸壳上二分查找即可。
7.更一般的动态规划问题
部分递推问题
Orz能在考场上切掉这种题的人
建立图论模型解决动态规划问题
对于某些不满足无后效性的问题,我们需要用其它的手段,建立图论模型只是其中一种,更多的情况下是乱搞。
动态规划这部分我就懒得贴代码了,随便找些题去切吧。见的多了就会做了。