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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章