主要内容 #
- 上台阶问题
 - 平面分割问题
 
1.上台阶问题 #
问题描述 #
请思考以下问题,并动手编写程序:
楼梯有n个台阶,上楼可以一步上一个台阶,也可以一步上两个台阶。一共有多少种上楼的方法?
问题分析 #
1. 假设有1个台阶,只有1种方法:

2. 假设有2级台阶,只有2种方法:


3. 假设有3级台阶
3.1 先爬1阶,接下来还有2阶台阶,那问题就是有2阶台阶怎么爬:

3.2 先爬2阶,接下来还有1阶台阶,那问题就是有1阶台阶怎么爬:

4. 假设有n级台阶
4.1 先爬1阶,接下来还有 n – 1 阶台阶,那问题就是有n – 1阶台阶怎么爬:

4.2 先爬2阶,接下来还有 n – 2 阶台阶,那问题就是有n – 2阶台阶怎么爬:

数学归纳法得出,有n阶台阶那么就是 n – 1 阶台阶和 n – 2 阶台阶爬上楼顶的方法的和。
公式: f(n) = f(n – 1) + f(n – 2) , 这不就是菲波那切数列数量求和吗?
编程求解 #
#include < iostream >
#include < vector >
using namespace std;
int climbStairs(int n) {
   //建立容器
   vector dp(n+1, 0);
   //设定边界值
   dp[0]=1;
   dp[1]=1;
   //循环求解
   for(int i=2;i<=n;i++){
      dp[i]=dp[i-1]+dp[i-2];
   }
   return dp[n];
   }
int main(){
   int n;
   cin >> n;
   cout << climbStairs(n) << endl;
   return 0;
}
算法优化
使用容器占用较大的空间,可以用p,q,r三个变量循环代替容器。

#include < iostream >
using namespace std;
int climbStairs(int n) {
   int p = 0, q = 0, r = 1;
      for (int i = 1; i <= n; ++i) {
         p = q; 
         q = r; 
         r = p + q;
      }
      return r;
    }
int main(){
   int n;
   cin >> n;
   cout << climbStairs(n) << endl;
   return 0;
}