趣学算法系列-动态规划
声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门,
原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多实例分析请查看原书内容
第四章 动态规划
动态规划解决复杂问题的思路也是对问题进行分解,通过求解小规模的子问题再反推出原问题的结果。动态规划也是把原问题分解为若干子问题,然后自底向上,先求解最小的子问题,把结果存储在表格中,再求解大的子问题时, 直接从表格中查询小的子问题的解, 避免重复计算, 从而提高算法效率。
- 动态规划求解两个特性
(1)最优子结构 问题的最优解包含其子问题的最优解
(2)子问题重叠 有大量的子问题是重复的,记录结果,避免重复运算
(3)无后向性 决策仅受之前决策的影响,不影响之后各阶段的决策
- 动态规划秘籍
(1)分析最优解的结构特征。
(2)建立最优值的递归式。(也可以称为决策策略)
(3)自底向上计算最优值,并记录。
(4)构造最优解。
- 如何建立最优值的递推式
(1)定义最优子问题 确定问题的优化目标
(2)定义状态 决策的结果(状态) 最终的结果(状态)就是最终解
(3)定义决策和状态转换方程 状态递增的表达式(不一定是数学表达式)
(4)确定边界条件 实际上就是递归终结条件,无需额外的计算
分析原问题最优解和子问题最优解的关系。考查有多少种选择。得到最优解递归式。
以上的理解请不要陷入细节,更多的理解请从实际的案例中体会。问题的重复求解是动态规划提升的关键。
动态规划的典型应用
青蛙上台阶问题
棋盘格跳马问题实际案例分析-兔子出生问题(斐波那契数列)
问题描述
假设第 1 个月有 1 对刚诞生的兔子,第 2 个月进入成熟期,第 3 个月开始生育兔
子,而 1 对成熟的兔子每月会生 1 对兔子,兔子永不死去……那么,由 1 对初生兔子
开始, 12 个月后会有多少对兔子呢?如果是 N 对初生的兔子开始, M 月后又会有多少
对兔子呢?问题分析
第 1 个月,兔子A没有繁殖能力,所以还是 1 对。
第 2 个月,兔子A进入成熟期,仍然是 1 对。
第 3 个月,兔子A生了 1 对小兔b,于是这个月共有 2 对( 1+1=2)兔子。
第 4 个月,兔子A又生了 1 对小兔c。兔子B进入成熟期。共有3对( 1+2=3)兔子。
第 5 个月, 兔子A又生了 1 对小兔d, 兔子B也生下了 1 对小兔e。 兔子C进入成熟期。共有 5 对( 2+3=5)兔子。
第 6 个月,兔子ABC各生下了 1 对小兔fgh。兔子进入成熟期。新生 3 对兔子加上原
有的 5 对兔子,这个月共有 8 对( 3+5=8)兔子算法设计
(1)分析最优解的结构特征
前两个月都是 1 对兔子,而从第 3 个月开始,当月的兔子数等于前两个月的兔子数,如果把每个月的兔子数看作一个最小的子问题,那么求解第 n 个月的兔子数,包含了第 n−1 个月的兔子数和第 n−2 个月的兔子数这两个子问题。
(2)根据最优解结构特征,建立递归式
(3)自底向上计算最优值
(4)构造最优解
所求的树根即为当前问题的最优解伪代码详解
int Fib2(int n) { if(n<1) return -1; int F[n+1]; F[1]=1; F[2]=1; for(int i=3;i<=n;i++) F[i]=F[i-1]+F[i-2]; return F[n]; }