使用矩陣快速冪計算斐波拉契數列

2021-09-27 08:34:56 字數 1139 閱讀 5301

一.題目:

已知f[n]=f[n-1]+f[n-2],f[1]=1,f[2]=1,求給定n的f[n]

二. 思路

常見的方法就是動態規劃,這樣時間的複雜度為o(n)

還有一種更快速的方法:矩陣的快速冪

給出的遞推式可以看做狀態轉移矩陣,可以表示為: 

那麼f[n]和f[0],f[1]的關係可以表示為

如何暴力求解轉移矩陣的n-1方,求矩陣的次數為n-2次,每次兩兩矩陣相乘的複雜度為2*2*2,也就是時間複雜度為o(8*n)

反而比動態規劃高了

這裡就用到求矩陣快速冪的方法,將時間的複雜度降到o(8logn)

矩陣快速冪就是:比如我求解上面矩陣

的7次方冪t^7,因為用於動態規劃的轉移矩陣t都是方陣(好好想一下為什麼),t^2之後還是維度不變的方陣,比如t的維度是2*2,那麼t^2的維度還是2*2,也就是說維度不會隨著冪的增加而增加,所以對於7次方,我們分解成:(((t^2)*t)^2)*t

也就是將冪7分解成(2+1)*2+1

這樣的話求解矩陣乘的次數變成了4,這樣的話總的求解矩陣乘法次數n滿足logn三.python實現如下

import time

def mat_mul(t1,t2):

n=len(t1)#結果的行數

m=len(t2[0])#結果的列數

res=[[0 for i in range(m)] for j in range(n)]

for i in range(n):

for j in range(m):

res[i][j]=sum([t1[i][k]*t2[k][j] for k in range(len(t1[0]))])

return res

def fbi(n):

start = time.clock()

c=[[1,1],[1,0]]

res=[[1,1],[1,1]]

if 0>1

res=mat_mul(res,[[1],[1]])

elapsed = (time.clock() - start)

print("time used:",elapsed)

return res[0][0]

講的非常詳細,基礎:

又見斐波拉契(矩陣快速冪)

傳送門 2018年湘潭大學程式設計競賽 g 這是乙個加強版的斐波那契數列。給定遞推式 求f n 的值,由於這個值可能太大,請對 10 9 7 取模。第一行是乙個整數t 1 t 1000 表示樣例的個數。以後每個樣例一行,是乙個整數 n 1 n 10 18 每個樣例輸出一行,乙個整數,表示f n mo...

矩陣快速冪 斐波那契數列

time limit 1000 ms memory limit 128 mb 通過小l的不懈努力,他即將成為大神啦,他登上了大神專屬的頒獎臺。在頒獎台上,他即將領取代表著大神的無限榮譽的勳章。小l走上頒獎台後,在台上發現了乙個製作精美的盒子。榮譽勳章就在盒子裡面。小l發現這個盒子被上了鎖,在這個盒子...

矩陣快速冪 斐波那契數列

先來實現乙個矩陣相乘的函式吧。const int mod 10000 struct mat mat mat mul mat x,mat y 實現兩個矩陣相乘,返回的還是乙個矩陣。return res 其實和普通快速冪類似,只不過這裡需要得到的是乙個矩陣下面來實現乙個矩陣快速冪 int pow int...