动态规划: 「Dynamic Programming」
以上三个问题都是 dp 的一类问题,解法也一样。
dp 的解题思路最重要的就是寻找「状态转移方程」
状态转移方程往往依赖上一个结果的计算值:比如 斐波那契 以及 杨辉三角
对于「斐波那契」
f(n) = f(n - 1) + fn(n - 2)
对于「杨辉三角」(排除边界 case 1)
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
动规总能以一个数学公式进行表达
但 这并不是动规的精髓所在,寻在「状态转移方程」往往需要寻找「最优子结构」:可以从子问题的最优结果推出更大规模问题的最优结果。
刷了一些题目之后就会发现:基本上就是从一个小规模内求一个最大最小值。「一看就会,一写就废」
以 「使用最小花费爬楼梯」为例:
- 爬楼梯要么从第 0 步 开始,要么从 第 1 步开始。
- 对于第 i 次解决方案而言,要么是从 i - 1 过来,要么是从 i - 2 过来。那么 dp[i] 的最优解为
dp[i] = Math.min(dp[i - 2], dp[i - 1]) + cost[i]
- 对于结果而言,要么是从最后一步,要么是从前两步过来,因为最优的结果是:
Math.min(dp[dp.length - 2], dp[dp.length - 1]) |
/** |