目前做的题还是不够多,对DP的理解很浅显很片面,找出动态转移方程超难理解,这几天学习了几篇前人的博客结合自己做题的经验在这里总结一下。
贪心算法核心是在确定好排序规则后以最快的速度逼近目标,DP核心是以小目标来确定更大的目标,依次类推最后得出最终目标。
DP的核心思想
DP为什么会快?
无论是DP还是暴力,我们的算法都是在可能解空间内,寻找最优解。
来看钞票问题。暴力做法是枚举所有的可能解,这是最大的可能解空间。
DP是枚举有希望成为答案的解。这个空间比暴力的小得多。
DP过程概括
一言以蔽之:大事化小,小事化了。
将一个大问题转化成几个小问题;
求解小问题的解;
推出大问题的解。
设计DP算法
下面介绍比较通用的设计DP算法的步骤。
首先,把我们面对的局面表示为x。这一步称为设计状态。
对于状态x,记我们要求出的答案(e.g. 最小费用)为f(x).我们的目标是求出f(T).找出f(x)与哪些局面有关(记为p)(就是找出所以有可能的状态,找出最优状态),写出一个式子(称为状态转移方程),通过f§来推出f(x).
DP三大步骤
我是谁? ——设计状态,表示局面
我从哪里来?
我要到哪里去? ——设计转移
设计状态是DP的基础。接下来的设计转移,有两种方式:一种是考虑我从哪里来;另一种是考虑我到哪里去(过程的正推或反推),这常见于求出f(x)之后,更新能从x走到的一些解。这种DP也是不少的,我们以后会遇到。
总而言之,“我从哪里来”和“我要到哪里去”只需要考虑清楚其中一个,就能设计出状态转移方程,从而写代码求解问题。前者又称pull型的转移,后者又称push型的转移。