一、基本思想
将问题划分为更小的子问题,并通过求解子问题的解来推导出原问题的解。
在求解过程中,通过保存子问题的解,避免重复计算,提高了效率。
二、适用场景
动态规划通常适用于具有重叠子问题
和最优子结构
性质的问题。重叠子问题意味着问题的解可以通过递归的方式从子问题的解中得到。最优子结构意味着问题的最优解可以通过子问题的最优解推导得到。
三、求解步骤
-
定义子问题:将原问题划分为若干个子问题。
-
构建状态转移方程:定义子问题之间的关系,描述子问题之间如何通过已知信息推导出更大规模问题的解。
-
确定初始条件:确定最小子问题的解,作为递归或迭代的终止条件。
-
迭代求解:按照子问题的规模从小到大进行求解,保存子问题的解,逐步推导出原问题的解。
-
求解原问题:根据最终的子问题解得到原问题的解。
四、算法案例
题目:斐波那契数列问题
利用动态规划求解:
func fib(n int) int {
if n < 2 {
return n
}
// 创建一个数组用于存储子问题的结果
arr := make([]int, n+1)
arr[0] = 0
arr[1] = 1
// 利用迭代的手段不断求解子问题的父问题(自底向上)
for i := 2; i <= n; i++ {
arr[i] = arr[i-1] + arr[i-2]
}
return arr[n]
}