1. 程式人生 > >斐波那契數列高效遞迴求法

斐波那契數列高效遞迴求法

時間;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會一步步減小。通過這種遞迴的方式可以有效減少冗餘計算,很明顯,中間碰到的每個值都值被計算了一次。

-------------------------------------------------------------------

三、實現

#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;
}
這個演算法的時間複雜度就為O(n)了,是比較可觀的。