70.Climbing Stairs

很经典的递归题,爬楼梯的方法=最后走1步+最后走2步,所以很容易就能写出递归算法。然而发现超时了,知道需要使用动态编程。其实上面的也是动态编程的思路,只不过动态编程将中间结果保存,这样其实遍历一次就能得到结果。

现在重新思考了一下动态编程和分治的相同于区别:

相同点:都需要寻找子问题,由子问题的解得到最终解

不同点:分治可能除了子问题,还需要额外的操作,有时候额外的操作时间复杂度甚至超过了子问题。分治一般不会保存中间结果,所以通常和递归结合使用。

动态编程必须明确找到子问题,并且子问题必须和原问题一样(目前遇到的都是一样的),动态编程必然存在一个递推关系(显示或者隐示的),显示的即可以直接用数学公式表示出来,隐示的需要找到一个DAG(有向无环图)。最终将问题转换为如何从起点走到终点的路径选择问题。

递归:

 1 classSolution {
 2 
 3 public:
 4 
 5        int climbStairs(int n) {
 6 
 7               if (n == 1)
 8 
 9                      return 1;
10 
11               else if (n == 2)
12 
13                      return 2;
14 
15               else
16 
17                      return climbStairs(n - 1) +climbStairs(n - 2);
18 
19              
20 
21        }
22 
23 };

 

 

动态规划:

 1 class Solution {
 2 
 3 public:
 4 
 5        intclimbStairs(int n) {
 6 
 7               intdp[200];
 8 
 9               dp[1]= 1;
10 
11               dp[2]= 2;
12 
13               for(int i = 3; i <=n; i++)
14 
15                      dp[i]= dp[i - 1] + dp[i - 2];
16 
17               returndp[n];
18 
19              
20 
21        }
22 
23 };

 

posted @ 2016-11-21 17:15  Initial_Dream  阅读(102)  评论(0编辑  收藏  举报