动态规划理论:一篇文章带你彻底搞懂最优子结构、无后效性和重复子问题
什么样的问题可以用动态规划解决?解决动态规划问题的一般思考过程是什么样的?
一个模型三个特征理论讲解
动态规划能解决的问题有什么规律可循呢?总结为“一个模型三个特征”
一个模型:动态规划适合解决的问题的模型,该模型定义为“多阶段决策最优解模型”
一般用动态规划来解决最优问题,解决问题的过程,需要经历多个决策阶段,每个决策阶段对应一组状态,然后寻找一组决策序列,经过这组决策序列,能产生最终期望求解的最优解
三个特征:最优子结构、无后效性和重复子问题
1,最优子结构
问题的最优解包含子问题的最优解,即后面阶段的状态可以通过前面阶段的状态推导出来
2.无后效性
推导我们阶段的状态时候,只关心前面阶段的状态值,不关心这个是怎么一步步推导出来的,只有满足前面提到的动态规划问题模型,基本都会满足无后效性
3.重复子问题
不同决策序列,到达某个相同的阶段时,可能会产生重复的状态
“一个模型三个特征”实例剖析
有一个n*
n的矩阵w[n][n]
,矩阵中存储的都是正整数,需要将棋子从左上角移动到右下角,每次只能往右或者向下移动一位,把每条路径经过的数字加起来看做路径的长度,那么从左上角移动到右下角的最短路径长度是多少?
1 3 5 9
2 1 3 4
5 2 6 7
6 8 4 3 (1是起点,3是终点)
这个问题是否符合“一个模型”?
从(0,0)移动到(n-1,n-1)总和走2*(n-1)
步,每个阶段都有向右或者向下走两种决策,每个阶段都会对应一个状态集合,把状态定义为min_dist(i,j),i表示行,j表示列,min_dist(i,j)表达式的值表示从(0,0)到(i,j)的最短路径长度,所以这个问题是一个多阶段决策最优解问题,符合动态规划的模型
初始阶段0:1
阶段1:2 or 3
阶段2:5 or 1 or 5
阶段3:6 or 2 or 3 or 9
阶段4:8 or 6 or 4
阶段5:4 or 7
阶段6:3
是否符合“三个特征”?
用回溯算法解决这个问题,比如写一下代码,画一下递归树,发现递归树中有重复节点,重复节点表示从左上角到节点对应的位置有多种路线,说明这个问题有重复子问题
走到(i,j)这个位置,只需要关心(i-1,j),(i,j-1)两个位置对应的状态,并不关心棋子是通过什么样的路线到达这两个位置的,符合无后效性这个特征
min_dist(i,j)可以通过min_dist(i,j-1)和min_dist(i-1,j)两个状态推导出,符合最优子结构
两种动态规划解题思路总结
把解决动态规划问题一般有两个思路,状态转移表法和状态转移方程法
1.状态转移表法
能用动态规划解决的问题都可以使用回溯算法的暴力搜索解决,当我们拿到问题的时候先用简单的回溯算法解决然后定义状态,每个状态表示一个节点,画出递归树,看是否存在重复子问题,以此来寻找规律,看是否能用动态规划解决
找到重复子问题之后,有两种思路,一是直接用回溯加“备忘录”来避免重复子问题,二是使用动态规划解决方案,状态转移表法
状态转移表法是:先画出一个状态表,表一般是二维的,每个状态包含三个变量,行、列、数组值,根据决策的先后过程,从前往后,分阶段填充每个状态,将这个递推填表的过程,翻译成代码,就是动态规划代码
尽管大部分状态表都是二维的,如果问题的状态比较复杂&#x