- 计算机归根到底就是穷举解决问题,但是关键是如何“聪明”的穷举才是关键的,这就是算法的诞生,因此动态规划也是一种聪明的穷举。
- 解决多阶段决策过程最优化的一种数学方法。把多阶段问题变换为一系列相互联系的的单阶段问题,然后逐个加以解决
概念
求出f(n),只需要知道几个更小的f©。我们将求解f©称作求解f(n)的“子问题”。
能将大问题拆成几个小问题,且满足无后效性、最优子结构性质
- 无后效性:如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响。(未来与过去无关)
- 最优子结构性能:大问题的最优解可以由小问题的最优解推出
尽量缩小可能解空间
与递归区别:
- 动态规划:自底向上 - 直接从最底下,最简单,问题规模最小 的 f(1) 和 f(2) 开始往上推 ,直到推到我们想要的答案 f(20),这就是动态规划的思路,这也是为什么动态规划一般都脱离了递归,而是由循环迭代 完成计算。
- 递归:自顶向下 - 递归树(或者说图),是从上向下延伸 ,都是从一个规模较大的原问题比如说 f(20),向下逐渐分解规模,直到 f(1) 和 f(2) 触底 ,然后逐层返回答案 ,这就叫「自顶向下」
与暴力区别:
- 暴力做法是枚举所有的可能解,这是最大的可能解空间,在暴力算法中,可能解空间往往是指数级的大小
- DP是枚举有希望成为答案的解,自带剪枝,有可能把解空间的大小降到多项式级
状态转移方程
这里,引出「状态转移方程」这个名词,实际上就是描述问题结构的数学形式:可见列出「状态转移方程」的重要性,它是解决问题的核心 。很容易发现,其实状态转移方程直接代表着暴力解法。
解题关键:大事化小,小事化了
解题
设计DP算法
- 首先,把我们面对的局面表示为x。这一步称为设计状态。
- 对于状态x,记我们要求出的答案(e.g. 最小费用)为f(x).我们的目标是求出f(T).
- 找出f(x)与哪些局面有关(记为p),写出一个式子(称为状态转移方程),通过f§来推出f(x).
DP三连
- 我是谁? ——设计状态,表示局面
- 我从哪里来?
- 我要到哪里去? ——设计转移
设计状态是DP的基础。接下来的设计转移,有两种方式:
- 一种是考虑我从哪里来 (本文之前提到的两个例子,都是在考虑“我从哪里来”);(前者又称pull型的转移)
- 另一种是考虑我到哪里去 ,这常见于求出f(x)之后,更新能从x走到的一些解。这种DP也是不少的,我们以后会遇到。(push型的转移)
- 首先找到目前值的状态是怎么样的,也就是 f ( x ) f(x) f(x) , x x x就是题目要求的最值,总和
- 在解题的时候,找到状态转移方程,我的理解,所谓状态转移方程,就是此状态的值是由之前几个值决定的(从哪里来问题,多项式)或者是可以决定之后的几个值(到哪里去)。