題目:
定義fibonacci數列如下:
遞迴的方法,**如下:
#include
using namespace std;
int fibona(int n)
}int main()
從下往上計算,首先根據f(0)和f(1)計算f(2),再根據f(1)和f(2)求出f(3).......
依此類推就可以算出第n項了,時間複雜度為o(n),實際上就是用遞推。
long long fibonacci_solution2(unsigned n)
;if (n < 2)
return result[n];
long long fibminusone = 1;
long long fibnminustwo = 0;
long long fibn = 0;
for (unsigned int i = 2; i <= n; ++i)
return fibn;}
下面介紹一種時間複雜度是
o(logn)
的方法。在介紹這種方法之前,先介紹乙個數學公式:
=n-1
(注:表示乙個矩陣。在矩陣中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1)。)
有了這個公式,要求得f(n),我們只需要求得矩陣的n-1次方,因為矩陣的n-1次方的結果的第一行第一列就是f(n)。這個數學公式用數學歸納法不難證明。感興趣的朋友不妨自己證明一下。
現在的問題轉換為求矩陣的乘方。如果簡單第從0開始迴圈,n次方將需要n次運算,並不比前面的方法要快。但我們可以考慮乘方的如下性質:
/ an/2*an/2 n為偶數時
an=\ a(n-1)/2*a(n-1)/2 n為奇數時
要求得n次方,我們先求得n/2次方,再把n/2的結果平方一下。如果把求n次方的問題看成乙個大問題,把求n/2看成乙個較小的問題。這種把大問題分解成乙個或多個小問題的思路我們稱之為分治法。這樣求n次方就只需要logn次運算了。
實現這種方式時,首先需要定義乙個2×2的矩陣,並且定義好矩陣的乘法以及乘方運算。當這些運算定義好了之後,剩下的事情就變得非常簡單。完整的實現**如下所示。
let a=
;int f(int n)
;int result[4];
power(a, n, result);
return result[0];
}void multiply(int a, int b, int _r)
void power(int a, int n, int _r)
int tmp[4];
power(a, n >> 1, _r);
multiply(_r, _r, tmp);
if (n & 1 == 1)
multiply(tmp, a, _r);
else
memcpy(_r, tmp, 4 * sizeof(int));
}
Swift學習 求Fibonacci數列
參考自 題目 定義 fibonacci 數列如下 看到斐波那契數列幾乎所有的程式設計師在第一時間的反應都是 遞迴 沒錯了,作為和漢諾塔一樣的經典遞迴問題,我們幾乎毫不猶豫就可以寫出如下的 func fibonacci 1 index int int else if index 1 else 分析2 ...
C語言求Fibonacci數列
方法一 普通法 include include unsigned long fibonacci unsigned n 列印fibonacci intmain void printf athank you for you using.return exit success unsigned long ...
Fibonacci數列求餘 C語言
fibonacci數列求餘 c語言 問題描述 fibonacci數列的遞推公式為 fn fn 1 fn 2,其中f1 f2 1。當n比較大時,fn也非常大,現在我們想知道,fn除以10007的餘數是多少。輸入格式 輸入包含乙個整數n。輸出格式 輸出一行,包含乙個整數,表示fn除以10007的餘數。說...