主要内容 #
- 上台阶问题
- 平面分割问题
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; }