Fibonacci數(shù)列

Fibonacci數(shù)列

Fibonacci數(shù)列是一個(gè)非常美麗边臼、和諧的數(shù)列,有人說(shuō)它起源于一對(duì)繁殖力驚人崖堤、基因非常優(yōu)秀的兔子侍咱,也有人說(shuō)遠(yuǎn)古時(shí)期的鸚鵡就知道這個(gè)規(guī)律。
每一個(gè)學(xué)理工科的學(xué)生都知道Fibonacci數(shù)列密幔,F(xiàn)ibonacci數(shù)列由如下遞推關(guān)系式定義:

F(0)=0, F(1)=1, n>1時(shí)楔脯,F(xiàn)(n)=F(n-1)+F(n-2)。

每一個(gè)上過算法課的同學(xué)都能用遞歸的方法求解Fibonacci數(shù)列的第n+1項(xiàng)的值胯甩,即F(n),以下為相關(guān)算法的代碼:

int Fibonacci (int n)
{
    if (n <= 0) return 0;
    else if (n == 1) return 1;
    else return Fibonacci(n-1) + Fibonacci(n-2);
  }

那么問題來(lái)了,對(duì)于以上這種算法,能否進(jìn)一步優(yōu)化?

分析與解法

解法一:遞推關(guān)系式的優(yōu)化

上面列出的算法是根據(jù)遞推關(guān)系式的定義直接得出的,它在計(jì)算F(n)時(shí),需要計(jì)算從F(2)到F(n-1)每一項(xiàng)的值,這樣簡(jiǎn)單的遞歸式存在著很多的重復(fù)計(jì)算,如F(5) = F(4) + F(3) , 在求F(4)的時(shí)候也需要計(jì)算一次F(3)的大小...等等昧廷。請(qǐng)問這個(gè)算法的時(shí)間復(fù)雜度是多少?
那么經(jīng)過分析我們可以知道優(yōu)化此類算法的重點(diǎn)在于減少重復(fù)計(jì)算。那么我們可以用一個(gè)數(shù)組存儲(chǔ)所有已計(jì)算過的項(xiàng)偎箫。這樣就可以達(dá)到用空間換取時(shí)間的目的木柬。在這種情況下,時(shí)間復(fù)雜度為 O(N),而空間復(fù)雜度也為O(N)。
那么有更快的算法嗎?

解法二:求解通項(xiàng)公式

如果我們知道一個(gè)數(shù)列的通項(xiàng)公式,使用公式來(lái)計(jì)算就會(huì)更加容易了淹办。那么問題的關(guān)鍵就是能不能把這個(gè)函數(shù)的遞推公式計(jì)算出來(lái)眉枕。
由遞推公式: F(n)=F(n-1)+F(n-2),知道F(n)的特征方程為:
x2 = x + 1 , 有兩個(gè)特征根x1,x2。
則通項(xiàng)為F(n)= A x1 n + B x2 n( n次方,本人對(duì)markDown語(yǔ)法不是很熟練所以在此加以說(shuō)明希望不要誤導(dǎo)到讀者,以上公式為:A倍 x1 的n次方) 速挑,其中A谤牡,B可以通過F(0)和F(1)計(jì)算出來(lái)。

解法三:分治策略

因?yàn)镕ibonacci數(shù)列是二階遞推數(shù)列,所以存在2*2的矩陣A姥宝,使得:

    [Fn Fn-1] = [Fn-1, Fn-2]*A
  通過遞推可以求得A={{1, 1}{1, 0}}
  且:[Fn Fn-1] = [Fn-1, Fn-2]*A = [Fn-2, Fn-3]*A2= ... = [F1, F0]*An-1

剩下的問題就是求解矩陣A的方冪翅萤。
參考代碼如下:

1 #include <iostream>
 2 using namespace std; 
 3 
 4 typedef long long LL; 
 5 const int maxn = 2; 
 6 const int MOD = 100000007; 
 7 
 8 struct Matrix 
 9 {
10     LL m[maxn][maxn]; 
11 }; 
12 
13 Matrix A = {1, 1, 1, 0}; 
14 Matrix I = {1, 0, 0, 1}; 
15 
16 Matrix multi(Matrix a, Matrix b)
17 {
18     Matrix c; 
19     for (int i = 0; i < maxn; i++)
20     {
21         for (int j = 0; j < maxn; j++)
22         {
23             c.m[i][j] = 0; 
24             for (int k = 0; k < maxn; k++)
25             {
26                 c.m[i][j] += a.m[i][k] * b.m[k][j] % MOD; 
27             }
28             c.m[i][j] %= MOD; 
29         }
30     }
31     return c; 
32 }
33 
34 Matrix power(Matrix A, int k)
35 {
36     Matrix ans = I, p = A; 
37     while (k)
38     {
39         if (k & 1)
40         {
41             ans = multi(ans, p); 
42             k--; 
43         }
44         k >>= 1; 
45         p = multi(p, p); 
46     }
47     return ans; 
48 }
49 
50 int main(int argc, char *argv[])
51 {
52     int n; 
53     while (cin >> n)
54     {
55         if (n <= 0) 
56         {
57             cout << 0 << endl;
58             continue; 
59         }
60         Matrix ans = power(A, n-1); 
61         cout << ans.m[0][0] << endl;
62     }
63 }

拓展

假設(shè)A(0)=1,A(1)=2腊满,A(2)=2断序。對(duì)于n>2,都有A(k)=A(k-1)+A(k-2)+A(k-3)糜烹。```

(1) 對(duì)于任何一個(gè)給定的n,如何計(jì)算A(n)漱凝?

(2) 對(duì)于n非常大的情況疮蹦,如n=260的時(shí)候,如何計(jì)算A(n)modM(M<100000)呢茸炒?```

 解答:

(1) [A(k) A(k-1) A(k-2)] = [A(k-1) A(k-2) A(k-3)]*B

其中B={{1, 1, 0}, {1, 0, 1}, {1, 0, 0}}愕乎。

(2)這個(gè)問題筆者思路如下,但并未通過代碼證實(shí):

A(n)modM取值為0壁公,1感论,2,...紊册,M-1比肄,為有限的,因此囊陡,三元組[A(k) A(k-1) A(k-2)]共有M3種可能芳绩。

因此,A(n)modM是周期數(shù)列撞反,而且妥色,周期最大為M3。

可以先求出周期T遏片,然后再求A[260]```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嘹害,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吮便,更是在濱河造成了極大的恐慌笔呀,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件线衫,死亡現(xiàn)場(chǎng)離奇詭異凿可,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門枯跑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惨驶,“玉大人,你說(shuō)我怎么就攤上這事敛助〈植罚” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵纳击,是天一觀的道長(zhǎng)续扔。 經(jīng)常有香客問我,道長(zhǎng)焕数,這世上最難降的妖魔是什么纱昧? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮堡赔,結(jié)果婚禮上识脆,老公的妹妹穿的比我還像新娘。我一直安慰自己善已,他們只是感情好灼捂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著换团,像睡著了一般悉稠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艘包,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天的猛,我揣著相機(jī)與錄音,去河邊找鬼辑甜。 笑死衰絮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的磷醋。 我是一名探鬼主播猫牡,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼邓线!你這毒婦竟也來(lái)了淌友?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤骇陈,失蹤者是張志新(化名)和其女友劉穎震庭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體你雌,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡器联,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年二汛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拨拓。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肴颊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渣磷,到底是詐尸還是另有隱情婿着,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布醋界,位于F島的核電站竟宋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏形纺。R本人自食惡果不足惜丘侠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逐样。 院中可真熱鬧婉陷,春花似錦、人聲如沸官研。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)戏羽。三九已至,卻和暖如春楼吃,著一層夾襖步出監(jiān)牢的瞬間始花,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工孩锡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酷宵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓躬窜,卻偏偏與公主長(zhǎng)得像浇垦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荣挨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容