动态规划

介绍

介绍来自 LeetCode

动态规划(英语:Dynamic programming,简称 DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

适用条件

1. 最优子结构

问题最优解包含的子问题的解也是最优的。

2. 无后效性

若干个状态值一旦确定,此后过程的演变只和这若干个状态值有关,和手段和路径无关。

3. 重叠子问题

思想

思想来自 LeetCode

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。动态规划往往用于优化递归问题,例如斐波那契数列,如果运用递归的方式来求解会重复计算很多相同的子问题,利用动态规划的思想可以减少计算量。

通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,具有天然剪枝的功能,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

递归->DP一般转化方法

想不出?不妨先递归,然后转化。

递归有n个参数,定义n维数组 (下标::递归函数参数取值范围),然后从边界值开始填充数组(递推)。相当于递归逆过程。

一般思路

1. 将原问题分解成子问题。

每个子问题的解保存在数组中。

2. 确定状态

状态 : 和子问题相关的各个变量的一组取值。

一个状态对应一个或多个子问题。

某个状态下的值=某个状态对应的子问题的解。

问题的状态集合=状态空间。

整个问题的时间复杂度是状态数目*计算每个状态所需的时间。

K个变量构成一个状态,即可用K维数组来存储它。

3. 确定一些初始状态(边界状态)的值。

4. 确定状态转移方程(递推公式)

状态的转移:如何从一个或多个已知的状态,推出另一个状态的值(人人为我递推型)。