斐波那契數列 --- 四層優化


斐波那契數列

 

起源

兔子問題:“假定一對大兔子每月能生一對小兔子,且每對新生的小兔子經過一個月可以長成一對大兔子,具備繁殖能力,如果不發生死亡,且每次均生下一雌一雄,問一年后共有多少對兔子?”

分析:第一個月兔子沒有繁殖能力,所以還是一對;兩個月后生下一對兔子,共有兩對;三個月后,老兔子生下一對,小兔子還沒有繁殖能力,所以一共是三對,以此類推,可以列出下表

表中1,1,2,3,5,8,13.....構成一個序列,這個數列有一個特點就是前兩項之和等於后一項

數學函數定義:


 

方法1(遞歸)

時間復雜度:O(N2),空間復雜度:O(N)

long long Fibonacci(unsigned int n)
{
    return n < 2 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
}

 

方法2(循環)

時間復雜度:O(N),時間復雜度:O(1)

long long Fibonacci(unsigned int n)
{
    int result[2] = { 0, 1 };
    if (n < 2)
        return result[n];

    long long fibNOne = 1, fibNTwo = 0, fibN = 0;
    for (int i = 1; i < n; i++)
    {
        fibN = fibNOne + fibNTwo;
        fibNTwo = fibNOne;
        fibNOne = fibN;
    }
    return fibN;
}

 

方法3(通項公式)

時間復雜度:O(logn),空間復雜度:O(1)

long long Fibonacci(unsigned int n)
{
    return (pow((1 + sqrt(5)) / 2, n) - pow((1 - sqrt(5)) / 2, n)) / sqrt(5);
}

 

方法4(矩陣乘法實現,最優解)

時間復雜度:O(logn),空間復雜度:O(1)

#include<iostream>
#include<string>
using namespace std;

//定義2×2矩陣;
struct Matrix2by2
{
    //構造函數
    Matrix2by2
    (
        long m_00,
        long m_01,
        long m_10,
        long m_11
    )
        :m00(m_00), m01(m_01), m10(m_10), m11(m_11)
    {
    }

    //數據成員
    long m00;
    long m01;
    long m10;
    long m11;
};

//定義2×2矩陣的乘法運算
Matrix2by2 MatrixMultiply(const Matrix2by2& matrix1, const Matrix2by2& matrix2)
{
    Matrix2by2 matrix12(1, 1, 1, 0);
    matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10;
    matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11;
    matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10;
    matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11;
    return matrix12;

}


//定義2×2矩陣的冪運算
Matrix2by2 MatrixPower(unsigned int n)
{
    Matrix2by2 matrix(1, 1, 1, 0);
    if (n == 1)
    {
        matrix = Matrix2by2(1, 1, 1, 0);
    }
    else if (n % 2 == 0)
    {
        matrix = MatrixPower(n / 2);
        matrix = MatrixMultiply(matrix, matrix);
    }
    else if (n % 2 == 1)
    {
        matrix = MatrixPower((n - 1) / 2);
        matrix = MatrixMultiply(matrix, matrix);
        matrix = MatrixMultiply(matrix, Matrix2by2(1, 1, 1, 0));
    }
    return matrix;
}
//計算Fibnacci的第n項
long Fibonacci(unsigned int n)
{
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;

    Matrix2by2 fibMatrix = MatrixPower(n - 1);
    return fibMatrix.m00;

}

int main()
{
    cout << "Enter A Number:" << endl;
    unsigned int number;
    cin >> number;
    cout << Fibonacci(number) << endl;
    return 0;
}

 

 

斐波那契數列的應用題:

1 青蛙跳台階問題

一只青蛙一次可以跳上1級台階,也可以跳上2級台階。求該青蛙跳上一個n級的台階總共有多少種跳法。

提示:f(n) = f(n-1) + f(n-2)

擴展題:

一只青蛙一次可以跳上1級台階,也可以跳上2級台階......也可以跳上n級台階。求該青蛙跳上一個n級的台階總共有多少種跳法。

提示:f(n) = 2n-1

2 如果我們用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問8個2*1的小矩形無重疊地覆蓋一個2*8的大矩形,總共有多少種方法?

提示:f(8) = f(7) + f(6)

 

參考:

https://blog.csdn.net/qq_41035588/article/details/81814547

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM