赞
踩
一提到动态规划,大多数人都想到许许多多的名词,如什么状态转移方程什么的;要不就想到教材书上严谨而又晦涩难懂的对于动态规划的介绍;也有人想到高中的通项公式或数列题等等。然后脑子就开始晕了,感觉其他的入门算法都可以理解,但是到了动态规划就好难学会,也不禁产生出一种挫败的念头。不过别急,本人用我掌握动态规划的历程带你理解动态规划,让你成功进入动态规划的领域。
在使用动态规划前,先了解为什么使用动态规划。动态规划问题的一般形式就是求最值,比如最少硬币,最大背包价值,最短路线等等。既然要求最值,那么最简单的方法是啥?当然是一个个找呗。比如从十个人中找到最高那个,把所有可能的答案找一遍就可以得到最值了。所以动态规划的基础就是穷举。
但是动态规划的穷举和一般的穷举还不太一样,因为这类问题存在重叠子问题,如果暴力穷举的话效率会极其低下,所以需要一张表来优化穷举过程,避免冗余的计算。另外,虽然动态规划的核心思想就是穷举求最值,但是问题可以千变万化,穷举所有可行解其实并不是一件容易的事,只有得到正确的状态转移方程才能正确地穷举。
以上提到的重叠子问题、状态转移方程就是动态规划中的两个要素。这两要素的意思等会具体讲解,在实际的算法问题中,写出状态转移方程是最困难的,接下来的思维方式,将会辅助你思考状态转移方程。
斐波那契数列的数学形式就是递归的,写成代码就是这样:
int fib(int N) {
if (N == 1 || N == 2) return 1;
return fib(N - 1) + fib(N - 2);
}
这个不用多说了,学校老师讲递归的时候似乎都是拿这个举例。我们也知道这样写代码虽然简洁易懂,但是十分低效,低效在哪里?
该图说的是想要计算原问题 f(20),我就得先计算出子问题 f(19) 和 f(18),然后要计算 f(19),我就要先算出子问题 f(18) 和 f(17),以此类推。最后遇到 f(1) 或者 f(2) 的时候,结果已知,就能直接返回结果,递归树不再向下生长了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。