一般的,我们常用的解决问题的方法有暴力解决法、贪心法和动态规划法。在你遇到一个问题怎么想都想不出其解法的时候,很可能就需要用到动态规划了;在你的题目中出现最优、最多、最好等字眼的时候,很可能可以使用动态规划问题来解决了。
那么什么是动态规划呢?动态规划和分治思想、递归有着千丝万缕的关系。简单来说,递归就是在程序运行的过程中调用自身的一种编程技巧;动态规划通过寻找过程状态转移方程,将一个问题分解为子问题求解,但是子问题之间可能会有重复,因此如果单纯的使用递归方法来实现动态规划问题时间复杂度会比较高。不过动态规划问题的本质就是递归,这是因为我们在分析动态规划问题的过程中,需要状态转移方程,这个状态转移方程本质上就是递归。后面实现的过程中是否使用递归只是实现的不同而已,其本质就是递归。
动态规划有三个最基本的元素:最优子结构、状态转移方程和边界。状态转移方程用于描述将当前状态的解分解为更小状态的关系式;边界即状态转移方程的截止条件;最优子结构即确保通过状态转移方程所选择的子问题也能给出最优的解。
以最最基础的fibnacci问题为例:其基础的递推关系式为:
fib(i)=max{1 & i<3 fib(i-1)+fib(i-2)}
如果现在需要计算fib(5),按照规则需要计算fib(4) + fib(3),然后分别计算fib(4)和fib(3)
方法一:递归
采用递归实质上就是按照上图中的二叉树的先序遍历的顺序执行,其中每有一个节点就代表执行一次,因此其时间复杂度是O(2^n),这种递归解法太暴力了,时间复杂度太高
方法二:自底向上的迭代法
采用递归的方法始终会有较大的空间消耗,而采用自底向上的迭代方法可以将空间复杂度降低到O(1)级别。
。