动态规划:将递归算法重新写成非递归算法,让后者把那些子问题的答案系统的记录在一个表内,利用这种方法的技巧叫做动态规划。
此处黑人问号?????????
概念太抽象,还是具体上一点动态规划的例子吧
例1:计算斐波那契数:f(n) = f(n-1) + f(n-2) , f(0)=1 , f(1)=1
根据递推公式,我们可以很容易的写出计算斐波那契数的递归函数程序:
int Fibonacci( int N ){
if(N<=1)
return 1;
else
return Fibonacci(N-1)+Fibonacci(N-2);
}
程序写完很开心,可是编译运行后你会发现,此处黑人问号, what??????
很不幸,超 时,
怎么会酱紫呢?查了半天,你会发现,简单的去模仿递归算法,效率灰常的低,比如f(4)=f(3)+f(2),f(3)=f(2)+f(1),重复计算了f(2),而且随着N的增大,重复计算的规模将达到恐怖级别
那怎么办呢?好办,就是预先用一个表来保存已经算出的值,对已经解过的子问题不再进行递归调用,那这样就可以避免爆炸增长了
现在用迭代 替代 递归重新写一下以上程序:
int Fibonacci ( int N ){
int i=,last,NextToLast,Answer;
if(N<=1)
return 1;
last=NextLast=1;
for(i=2;i<=N;++i){
Answer=last+NextToLast;
NextToLast=Last;
last=Answer;
}
return Answer;
}
动态规划好用吧,直接将时间复杂度降低到了O(n)
例2:常敲代码手不软的博客,教你彻底学会动态规划入门篇,由于不能转载,此处放一下链接,http://blog.csdn.net/baidu_28312631/article/details/47418773,讲的非常的好,由浅入深讲解动态规划
例3:依然是常敲代码手不软的博客,教你彻底学会动态规划进阶篇,由于不能转载,此处放一下链接,http://blog.csdn.net/baidu_28312631/article/details/47426445
例4:就是以下两个最长递增子序列的问题
下面这两个题目归根结底都是求最长递增子序列问题,本质解法都是动态规划:
一、问题描述
题目一:
题目描述
计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依
次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。 你的任
务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形
题目二:
题目描述
Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道
为什么?你能替Redraiment研究他最多走的步数吗?
样例输入
6
2 5 1 5 4 5
样例输出
3
提示
Example:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5
从第5格开始走最多有2步,4 5
所以这个结果是3