DP思想总结收集+实例:走台阶问题

图片来源:各大CSDN博主博客,视频,以及程序员小灰(微信公众号)

 

动态规划(dynamic programming)思想 

朴素递归算法之所以效率很低,是因为它反复求解相同的子问题。因此,动态规划方法仔细安排求解顺序,对每个子问题只求解一次,并将结果保存下来。如果随后再次需要此子问题的解,只需查找保存的结果,而不必重新计算。因此,动态规划方法是付出额外的内存空间来节省计算时间,是典型的时空权衡的例子。而时间上的节省可能是非常巨大的:可能将一个指数时间的解转化为一个多项式时间的解。如果子问题的数量是输入规模的多项式函数,而我们可以在多项式时间内求解出每个子问题,那么动态规划方法的总运行时间就是多项式阶的。 

 

*******动态规划一定要找递推公式!!!******* 

 

https://www.zhihu.com/question/23995189 

 

对于DP的各种理解: 

动态规划的核心是定义状态和状态转移方程(注意,关键在于定义方程而非关注递推式的求解方法) 

动态规划就是 使用递归的思路 找到正确的算法步骤使得得到正确的解,然后使用迭代的方式写出来。(如此便验证了那句自顶向下的考虑问题,自底向上的解决问题) 

 

上图中最右边流程即为递归,左边为迭代(递归的思考,迭代的解决) 

          

 

 

 

 

 

动规中三个重要概念: 状态转移方程  边界   最优子结构 

 

动态规划走台阶: 

 

有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法。 

 
 

比如,每次走1级台阶,一共走10步,这是其中一种走法。我们可以简写成 1,1,1,1,1,1,1,1,1,1。 

再比如,每次走2级台阶,一共走5步,这是另一种走法。我们可以简写成 2,2,2,2,2。 

 

 我们想走到10,如果一次只能走一步或走两步。那么,不考虑之前的台阶。想走到10只有从9走一步或从8走两步。(这便是重构解,把大问题划分为小问题。) 

此时我们假设  从0-9 一共有X种走法  那么此时的从0-10 也是X中走法 

而0-8一共有Y种走法  那么在所有情况上再加两步到10  还是Y中走法  

 

所以 最后走到10步一共有X + Y种走法 

 

   

 

 

 

 

 

那么  从这一步我们便可以得出一个结论。 

 

0-10级台阶的走法数量 = 0-9级台阶的走法数量 + 0-8级台阶的走法数量 

 

F(10) = F(9) + F(8)(F9  F8 分别是10的最优子结构) 

 

同理 F(9) = F(8) + F(7)      F(8) = F(7) + F(6) 

 

而且当台阶有两级的时候有两种走法 当台阶为1时只有1种走法 

 

由此可以归纳出  

F(1) = 1 

F(2) = 2    //  1 和 2 是边界 

F(n) = F(n - 1) + F(n- 2)(n >= 3)  //状态转移方程 

 

//以上便是问题建模   接下来是求解部分 

若 简单的使用递归求解,则会造成大量重复计算问题。 

 

 

 

由此可以看出大量重复计算 

 

那么 ,如何解决?  可以把结果都放在一个数组里,这个数组被称为备忘录,也可以如下:使用一个哈希。 

 

 

 

基于哈希的递归: 

 

如此 时间空间复杂度便都是o(n) 

 

但这还不是真正的动态规划实现。时间复杂度已经不能再小了,那么能不能把空间复杂度进一步缩小? 

 

这便验证了DP的又一个特点:自顶向下的分析问题,自底向上的求解问题。 

 

那么 : 

 

如此变成了o(1)的空间复杂度 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值