1. 怎么理解动态规划
我记得 quora 上有一个回答是这么说的:
- 首先在一张纸上写下 1+1+1+1+1+1+1+1=?
- “它等于多少呢?”
- 我们会立即脱口而出,“等于 8!”
- 如果我们在左边添一个 +1,会等于多少呢?”
- 不用想,“等于 9!”
- “为什么你会计算得这么快呢?”
- “ 因为 8+1=9,我们没有重新计算 1+1+1+1+1+1+1+1+1 的值 8,再次计算时只需在 8 的基础上再加 1 就可以了。
dp 的策略也是如此,通过记住一些子问题的解来节省时间,这就是它的精髓。 所以,如果一个问题的子问题会被我们重复利用,我们则可以考虑使用动态规划来解决它。
2. 分治与动态规划
-
共同点:二者都要求原问题具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小(小到很容易解决的程序)的子问题.然后将子问题的解合并,形成原问题的解.
-
不同点:1. 分治法将分解后的子问题看成相互独立的,通过用递归来做。2. 动态规划将分解后的子问题理解为相互间有联系,有重叠部分,需要记忆,通常用迭代来做。
2. 什么是状态压缩
一般来说,动态规划使用一个一维数组或者二维数组来保存状态。
比如 42.接雨水 中,我们使用一维数组 dp[i] 表示下标 i左边最高柱子的高度。dp[i] 包含了两个信息:
- 下标 i 左边的柱子
- 最高的高度值
比如 10.正则表达式匹配 中,我们使用二维数组 dp[i][j] 表示 字符串 s 的前 i 项和 t 的前 j 项是否匹配。dp[i][j] 包含了三个信息:
- s 的前 i 项
- t 的前 j 项
- 是否匹配
利用二进制以及位运算来实现对于本来应该很大的数组的操作,这就是状态压缩,