斐波那契數列高效遞迴求法
時間;2014.05.19
地點:圖書館
-------------------------------------------------------------------
一、簡述
前面給出了一種斐波那契數列解法的矩陣冪方法,這是最高效的方法,時間複雜度為O(log)。正常來說通過遞推公式 F(n)=F(n-1)+F(n-2)直接來計算F(n)效率是很差的,因為這裡會涉及很多冗餘計算,比如求F(5),我們要求【F(4)和F(3)】,【要求F(4)則得求F(3)和F(2),要求F(3)得求F(2)和F(1)】...等等,於是這裡有好多數都設計要求重複計算,可以通過一顆二叉樹來展開,所以這樣的遞迴雖然使大問題化解為子問題了,但子問題的個數迅速膨脹而且還包含了重複的子問題。
-------------------------------------------------------------------
二、不同一般的遞迴
首先關係依舊,即 F(n)=F(n-1)+F(n-2),F(0)=0,F(1)=1,,有序列如下,假如我們要求F(6).
t0t1t2t3 t4t5t6t7t8... 本序列以0 和1開始,求的是F(6)
0112 3581321..
t0t1t2t3 t4t5t6t7.... 本序列以1和1開始,上面的F(6)對應現在的F(5)
1123 581321...
....
....
以此規則繼續往下面走,我們甚至可以假設一個滑動視窗,該視窗最初佔據起始序列的兩個值,然後每遞迴以此,向後滑動一個距離,當然離要求的目標也就靠近一次,最終即滑動視窗會佔據要求的值,而我們知道,每次滑動視窗移動佔據的值是很容易求得。如此,通過滑動視窗可以一步步縮減問題規模,在這裡表現為F(n)中的n會一步步減小。通過這種遞迴的方式可以有效減少冗餘計算,很明顯,中間碰到的每個值都值被計算了一次。
-------------------------------------------------------------------
三、實現
這個演算法的時間複雜度就為O(n)了,是比較可觀的。#include<iostream> int AdditiveSequence(int n, int t0, int t1) { if (n == 0) return t0; if (n == 1) return t1; return AdditiveSequence(n - 1, t1, t0 + t1); } int Fibonacci(int n) { return AdditiveSequence(n, 0, 1); } int main() { int n; std::cin >> n; std::cout << Fibonacci(n) << std::endl; return 0; }