快速冪
斐波那契數列,說起來大家都很熟悉,在練習程式設計的時候,也會經常被拿來作為例子這也是最常見的解法了,在最開始學習程式設計的時候,老師經常用這個例子。
因為他的定義就是遞迴的,用它可以顯而易見地提出遞迴的思想,n=
0和n=
1 作為遞迴基,其他的數分別遞迴求解 fn
=fn−
1+fn
−2。
int fib(int n)
但是很容易地就會發現,這個思路十分清晰的演算法太慢了。因為他們中的很多值在被重複地計算,例如 f5
=f4+
f3, f4
=f3+
f2, f3
就被重複地計算了,重複的部分增加的非常快,一旦當
n 大於 40 多時,就已經很難進行計算了。
這裡我們可以利用動規的思想來進行計算,複雜度都能降到 o(
n)。也是最簡單的,可以先開乙個陣列,並且在每次計算出結果後,儲存下來,就可以避免重複計算。
int f[10000];
int fib(int n)
從上面的定義方程就可以看出來,每乙個值只與前面的數有關於後面的數無關,這樣就可以從前往後依次計算(問題比較簡單,想法太順理成章了,動規得太不明顯了,但的確是動規)
int fib(int n)
if(n<=2) return f[n];
for(int i=3; i
<=n; i++)
return f[2];
}
當然平時做題時還是會開乙個陣列進行儲存,以後查詢時就是 o(
1)的複雜度了。
int f[10000];
int init()
int fib(int n)
上面的演算法,已經達到了o(
n)的複雜度,已經是非常優秀的了,但是當我們需要求解很大的答案是,例如 1000000000 之類,那麼也是很耗費時間的,或者說我們需要查詢的次數比較少,比較分散,那麼我們浪費的空間就比較大。下面利用矩陣就是另外一種求解的方法。
利用矩陣的性質我們可以得到下面的結論 (f
n+1f
nfnf
n−1)
∗(11
10)=
(fn+
1+fn
fn+f
n−1f
n+1f
n)(利
用fib
數列的定
義)=(
fn+2
fn+1
fn+1
fn)
而我們令 n=1, 則 (f
n+1f
nfnf
n−1)
=(11
10)
綜上,我們可以得出這樣的結論 (f
n+1f
nfnf
n−1)
=(11
10)n
理論有了,我們就可以類推數的快速冪來計算矩陣的快速冪。
// 數的快速冪
int quick_pow(int a, int n)
return n;
}
矩陣快速冪,需要自己寫矩陣的乘法,然後直接套用數的快速冪的模板就行
// 矩陣快速冪
struct matrix
return temp;
}};int solve(int n)
return re.data[0][1];
}
例題:poj3070 - fibonacci 解題報告 斐波那契數列求解
斐波那契數列是一種常見的數列,其滿足下面兩個條件 f0 f1 1 fn fn 1 fn 2 斐波那契數列求解def fib1 n if n 2 return 1 return fib1 n 1 fib1 n 2 不適用遞迴 python def fib2 n f1 f2 1 for i in ran...
斐波那契數列O logn 的求解方法
前言 是的,沒錯,斐波那契數列除了遞推 遞迴演算法之外,還有更加高效的求解方法,那就是矩陣運算 快速冪。思路 可以先利用矩陣運算的性質將通項公式變成冪次形式,然後用平方倍增 快速冪 的方法求解第 n 項。首先我們定義向量 xn an an 1 邊界 x1 a1 a0 然後我們可以找出矩陣 a 111...
Matlab求解斐波那契數列
下面是乙個matlab的指令碼函式,用於求解菲波那切數列,而且可以判斷輸入是否符合實際情況 function fibona n 斐波那契數列,前兩項之和等於第三項 f n f n 1 f n 2 第一項和第二項分別都是1 f 1 1,f 2 1 程式主題 if n 3 disp n warning ...