一、一般使用场景
常用于多阶段决策问题 最优解问题
区别于贪心算法只考虑眼前的局部利益 动态规定求解的是整体的最优值
如:求A到B的最短路径
A出发可达 A1 A2 A3
A1 出发可达 B1 B2
A2 出发可达 B2 B3
....
二、特点
最优子结构 : 最优解的问题可以由子问题的最优解转换而来(就是DP状态转移方程式,难点所在)
无重复子问题: 子问题不会重新计算 这个是动态规划算法的价值所在,否则直接使用递归即可(代码更易读 CleanCode)
无后效应:由子问题的状态向目标演进时 不用考虑子问题的状态如何而来 不会影响下一阶段的选择 (此点需要注意,DP方程式无法推导想想是否满足无后效应)
一个例子:走方格 不允许重复走,从某点A向后演进时,那只能考虑3个方向,点A如何而来影响了向后的决策 ,这就不满足无后效应了
三、解题步骤
a. 确定DP方程式
什么是状态 如何转移
b. 确定初始状态
c. 规划一条路径 依次求解这条路上每个阶段每个选择的值,向后递推,直到目标。
(一般可以画一个二维决策表,就是一个填表的过程)
四、例子
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行左右相邻的两个节点上
例三角形二维数组 ori,如下:
[
[2],
[3,4],
[6,5,7],
[1,7,9,5,4]
]
1、先确定DP方程式 (需要考虑什么是状态)
dp[i][j] : 表示第i行 第j列 到底部的最短距离
dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + ori[i][j]
2、确定初始状态
dp[6][i] = ori[6][i] (假设有7行)
3、从初始到目标 规划的路演进
dp[5][0] dp[5,1] ....dp[5][j]
dp[4,0] dp[4,1],...dp[4][j]
.....
其他的典型例子:背包问题、最长公共子列序列等
原文地址:https://www.cnblogs.com/yangfei629/p/12465291.html