Dynamic Programming(DP)在ICPC和各路信息学竞赛中被视作一个高深烧脑的部分,而我在学习了USC的CSCI-570的相关部分之后竟得到了“不过如此”的体会。虽然心里非常明白这种感觉是在570这门课重视算法设计而轻视代码实现的基础上才能形成的,不足以作为自我膨胀的资本,但是还是想趁着这股高兴劲儿写一点技术总结,以备后用。
目前的打算是把570涉及的知识点都记录一下作为知识储备,辅以刷题练习巩固(顺带熟悉语言和练手感),有需要的话再拿其他的教材看一看更高深的数据结构和算法,
内容安排:
1. DP的原理和例2. DP的一般构造过程和典型问题3. DP构造过程中应该注意到的几个侧面4. 几类典型的DP问题5. 在OJ上刷题
3. DP构造过程中应该注意到的几个侧面
- DP对问题分化的完整性:
- DP的状态域是对搜索域的重新划分, 本质上是一次变换域上的暴力搜索, 使用DP思想设计算法解决问题的本质是用新的视角分解搜索域,因此不仅要注意搜索域分解的可行性/迭代性/重叠性, 还要注意搜索域分解的完整性;
- DP问题的完整性仅凭思索很难形成解题自信, 往往需要参照标准答案形成思维惯性用模板解决部分类型的问题.
- DP问题的边界条件:
- DP问题的边界条件本质上是对代码逻辑中的起始数据的规定, 而它又可以被看做是解题人对自己如何理解子问题的一种解释或者声明. 这里可以分化出两个方面:
- 1. 需要哪些边界条件? 我们只需要画出算法中记忆数组的图, 思考问题从何开始, 填表方向和填表过程中必须用到的记忆单元即可, 只要有足够的边界值使得算法能顺利运行即可, 当然这里也需要一些练习.
- 2. 如何规定边界的值? 我们要兼顾对子问题的理解和算法逻辑, 通常可以先根据对子问题的理解试填表, 然后根据算法逻辑人工验证边界条件的的可行性, 根据算法需要调整边界条件设置. 这个方法也适用于思考逆向DP的解法.
4. 几类典型的DP问题
- 递归定义类型
- 线性选择类型
- (图)最短路类型
- Split类型
- 简单树形DP
- 简单逆向DP