动态规划(Dynamic Programming,DP)是一种用来解决一类最优化问题的算法思想
动态规划
- 将一个复杂的问题分解成若干个子问题,
- 通过综合子问题的最优解来得到原问题的最优解
会将每个求解过的子问题的解记录下来,这样可以避免下一次的重复计算。
- 递归写法(记忆化搜索)【自顶向下Top-down Approach】
- 递推写法 【自底向上Bottom-up Approach】
- 重叠子问题(Overlapping Subproblems):
一个问题可以被分解为若干个子问题,且这些子问题会重复出现。
只要记录下重叠子问题的解,下次碰到相同的子问题可以直接使用结果。
- 状态转移方程:
(dp[i][j]称为状态)
- 边界:可以直接确定结果的部分
总是从边界出发,通过状态转移方程,扩散到整个dp数组
- 最优子结构(Optimal Substructure):
一个问题的最优解可以由子问题的最优解推导而来——具有最优子结构。
- 分治:都是将原问题分解成子问题。
分治法分解出的子问题是不重叠的,因此分治法解决的问题不拥有重叠子问题。
(大问题->多个小问题,所有小问题的解合并->大问题的解) ,多个小问题彼此不完全相同。
- 贪心:都是要求拥有最优子结构。
类似“自顶向下”,并不等待子问题求解完毕后,再选择使用哪一个。
而是通过一种策略直接选择一个子问题去求解,没被选择的就不去求解了,直接抛弃。
它总是在上一步选择的基础上继续选择,因此整个过程以一种单链的流水方式进行。
显然这种所谓的“最优选择”的正确性需要用归纳法证明,并不一定是正确的。
而动态规划则总是考虑所有子问题,并选择继承能得到最优结果的哪个。
对于暂时没被继承的子问题,并不抛弃,由于重叠子问题的存在,后期仍然可以被纳入到全局最优结果中。
贪心是一种壮士断腕的决策,只要选择了就不后悔;
动态规划则要看哪个选择笑到了最后,暂时领先说明不了什么。