C++刷题笔记:动态规划


斐波那契数列

在这里插入图片描述

最简单的递归法:
存在大量的重叠子问题,时间复杂度为 O(2n)O(2^n),很慢,会超时。

class Solution {
public:
    int Fibonacci(int n) {
        if(n==0 or n==1) return n;
        return Fibonacci(n-1) + Fibonacci(n-2);
    }
};

动态规划: 直接从子树求得答案,过程是从下往上,时间复杂度:O(n),空间复杂度:O(n)

class Solution {
public:
    int Fibonacci(int n) {
        if(n==0 or n==1) return n;
        int a{0}, b{1}, c;
        for(int i=2; i<=n; i++){
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }
};

青蛙跳台阶

题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

分析:
假设 f[i]f[i] 表示跳上第 ii 个台阶的方法数,而第n个台阶可以是由第n-1个台阶跳上的,也可以是由第n-2个台阶跳上的,所以方法数 f[n]=f[n1]+f[n2]f[n] = f[n-1] + f[n-2] ,且初始条件 f[1] = 1,f[2] = 2. 本质上还是斐波那契数列。不再附代码了。


变态跳台阶

题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

分析:
假设 f[i]f[i] 表示跳上第 ii 个台阶的方法数,求 f[n]f[n]

假设现在已经跳到了第 n 个台阶,那么前一步可以从哪些台阶到达呢?

  • 如果上一步跳 1 步到达第 n 个台阶,说明上一步在第 n-1 个台阶,而跳到第n-1个台阶的方法数为f[n-1];
  • 如果上一步跳 2 步到达第 n 个台阶,说明上一步在第 n-2 个台阶,而跳到第n-2个台阶的方法数为f[n-2];
  • 。。。
  • 如果上一步跳 n-1 步到达第 n 个台阶,说明上一步在第 1 个台阶。已知跳到 第1个台阶的方法数为f[1] = 1
  • 如果上一步跳 n 步到达第 n 个台阶,说明上一步在第 0 个台阶。已知跳到 第0个台阶的方法数为f[0] = 0

那么总的方法数就是所有可能的和:f[n] = f[n-1] + f[n-2] + … + f[1]
显然初始条件还是 f[1] =1, f[2] = 2

继续分析:

f[n] = f[n-1] + f[n-2] + … + f[1], 那么 f[n-1] 呢?
显然,f[n-1] = ff[n-2] + … + f[1]
原来如此:f[n] = f[n-1] × 2

继续分析:

累乘法:
f[n] = f[n-1] × 2
f[n-1] = f[n-2] × 2

f[3] = f[2] × 2 = 2 × 2
所以:f[n] = pow(2, n-1)

return pow(2, n-1);
return 1 << (n-1);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章