动态规划用于就解决包含重叠子问题的问题,其中每一个子问题的状态都是由上一个状态推导出来的。
# 基础
动态规划的一般步骤:
- 确定dp数组和其下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
# 实践
# 斐波那契数
- 动规,dp数组代表第i个数,和题目直接对应
1 | |
# 爬楼梯
- 动规,dp表示到第i级台阶可能的方法
1 | |
# 使用最小花费爬楼梯
- 动规,dp表示到第i级台阶可能的方法,最后一步没有花费,取最小值
1 | |
# 不同路径
- 动规,dp表示到第i,j可能的路径
1 | |
# 不同路径 II
- 动规,dp表示到第i,j可能的路径,加入障碍物后,所以障碍物位置的路径变为0
1 | |
# 整数拆分
- 动规,dp表示i的最大面积,对于每个拆分的数i,从1开始遍历j到i-1,最大面积是 (i - j) * j 和 i - j 的最大面积 * j
1 | |
# 不同的二叉搜索树
- dp为节点数为i的二叉树数量,等于所有j-1和i-j的数量组合累加(相加==i-1,去除了根节点),dp[0]为空节点,也可以算作一种
1 | |
# 青蛙过河
- dp为能否到第i个石子上,并且上一步跳k个单位,限制条件是在i块石子上最多能跳i,如果石子间距离大于i则一定不能到达终点,并且上次跳跃距离一定满足k <= i,如果不满足则可以停止跳跃,避免冗余计算。
能否调到,i表示当前所在位置,k表示上一次跳跃的距离的石头上
1 | |
# 分割等和子集
- 01背包问题,背包容量是sum/2,商品价值和重量均为元素的数值,背包如何正好装满,说明找到了总和为sum/2的子集,元素不可重复
1 | |
# 最后一块石头的重量 II
- 01背包,背包容量是sum/2,商品价值和重量均为石头的重量,如何装最大化价值的石头dp[target],另一部分没装的就是sum - dp[target],sum/2向下取正,sum > 2dp[target]
1 | |
# 目标和
- 01背包,加号的总和为x,要求x - (sum - x) = S,dp[j]表示装满容量为j的背包有dp[i]种方法,那么dp[j] += dp[j - nums[i]]就是把所有可能的方法都加起来
1 | |