斐波那契數列
起源
兔子問題:“假定一對大兔子每月能生一對小兔子,且每對新生的小兔子經過一個月可以長成一對大兔子,具備繁殖能力,如果不發生死亡,且每次均生下一雌一雄,問一年后共有多少對兔子?”
分析:第一個月兔子沒有繁殖能力,所以還是一對;兩個月后生下一對兔子,共有兩對;三個月后,老兔子生下一對,小兔子還沒有繁殖能力,所以一共是三對,以此類推,可以列出下表
表中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