算法与数据结构八日谈之二——动态规划

1.背包问题

01背包问题

转移方程为

f[i,j]=max(f[i1,jwi]+vi,f[i1,j])

转移条件为
jwj

这是最裸的动态规划问题之一,从这个问题可以扩展出很多新问题来
可以用滚动数组将空间复杂度优化至 O(n)

完全背包问题

在01背包的基础上多出来每个物品可以选择多次的条件
转移方程为

f[i,j]=max(f[i1,jkwi]+kvi,f[i1,j])

转移条件为
jkwj

与01背包并没有很大的区别

多重背包问题

与完全背包不同的是,物品可以多次选择但有次数限制
所以直接在完全背包的转移条件上加上即可

混合背包问题

将上述3种背包混合在一起
还是没有什么区别,只需转移时对物品分类讨论即可

条件背包问题

部分物品需要在满足其它物品的限制下才能使用
对于这种问题,记忆化搜索要比直接计算方便得多
方程其实还是没有什么变化,但在转移时要对条件进行相应的修改,同时也要考虑边界情况

2.树形动规

理论上这一节应该放在树论的部分,但在这里我们还是提一下。
因为树有很强的递归结构,我们可以考虑以同样的方式进行状态转移
对于大多数的树形动规问题,我们可以在遍历时求出其dp值
在处理完子树后将子树对当前节点的答案的贡献求出即可

3.区间动规

一般的区间动规解法大多相同:
先枚举区间的长度,然后从头到尾枚举每个区间
这样的话可以保证每个前驱状态已被算到,这两步的复杂度是 O(nlgn)
转移的时候要注意边界情况,即区间中只剩下一个元素时的处理方法

4.状压动规

在某些情况下部分元素的个数极少,这时候可以考虑指数级算法。
我们用一个二进制数表示集合中每个元素的状态,于是二进制的或就可以表示集合的并,且就表示集合的交,判断一个元素是否存在只需要判断该元素所对应的位置是否为1。然后在dp时枚举每个子集并进行状态转移,就差不多了。

5.数位动规

数位动规一般是进行一些对于数字本身的统计。对于这种问题的通用思想是一次单独考虑一种数字对答案的贡献,然后利用乘法原理来合并相同的问题。还有一些小技巧,对于一些问题可以考虑补齐一个数的前导零,这样在处理时更方便

6.动态规划的优化问题

决策单调性

对于某些动态规划问题,越靠前的状态转移的决策越好,那么就可以使用单调队列优化,单调队列可以保证存在于队列中的元素的dp值得单调性,在求当前状态的dp值时只需弹出队尾的元素直到满足转移条件。计算完后再将其插入队列中,并弹出不满足单调性的决策。

斜率优化

我们将一些状态转移方程写出来,如果i是由j转移的,那么j就比k要优,在同时满足决策单调性的情况下那么k就是不必要的状态。利用合适的方法把一种决策抽象到平面上的点,那么有可能成为决策的点会在一个凸壳上,于是在转移时在凸壳上二分查找即可。

7.更一般的动态规划问题

部分递推问题

Orz能在考场上切掉这种题的人

建立图论模型解决动态规划问题

对于某些不满足无后效性的问题,我们需要用其它的手段,建立图论模型只是其中一种,更多的情况下是乱搞。

动态规划这部分我就懒得贴代码了,随便找些题去切吧。见的多了就会做了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值