递归步骤:
1.定义递归函数,明确函数的功能,
2.查找问题与子问题的关系:
要采用自上而下,由大到小的方式
用递归表达式表示关系
3.根据递归伪代码补充函数的功能(画图)
4.分析时间复杂度
动态规划:
1.将每一个子问题的解记录下来,避免重复计算,一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。
2.采用由小到大的方式
3.动态规划法试图只解决每个子问题一次
「动态规划」中包含三个重要的概念:
-
【最优子结构】
-
【边界】
-
【状态转移公式】
-
在「 爬台阶问题 」中
f(10) = f(9) + f(8)
是【最优子结构】
f(1) 与 f(2)
是【边界】
f(n) = f(n-1) + f(n-2)
【状态转移公式】
区别
1.递归是从上而下(从大问题到小问题),而动态规划是由下而上(先解决小问题最后到大问题)
2.动态规划会储存每个小问题的结果,从而它的计算速度会比递归要快。(代价是动态规划的空间复杂度更高,即用空间换取的时间)
下面拿斐波那契函数举例
递归如下:
int fib(int n)
{
if(n==0||n==1)
return n;
return fib(n-1)+fib(n-2);
}
动态规划如下:
int fib(int n)
{
int F[100],i;
F[0]=0;
F[1]=1;
for(i=2;i<n;i++)
F[i]=F[i-1]+F[i-2];
return F[n-1];
}
总结:能用动态规划或者迭代,就不用递归,因为递归太耗堆栈了。效率不高。