日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

斐波那契数列求法

發布時間:2023/12/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 斐波那契数列求法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 求斐波那切數列的幾個方法:
    • 經典做法:
      • 遞推:
      • 動態規劃
    • 矩陣快速冪
      • 原理:
      • 代碼:
      • 例題:
    • 模擬過程

求斐波那切數列的幾個方法:

經典做法:

眾所周知:斐波那契數列的定義是f(n + 1) = f(n) + f(n - 1)
我們有兩種方式來實現:一個是遞歸,一個是動態規劃

遞推:

int dfs(int n) {if (n == 1)return 1;if (n == 2)return 2;return dfs01(n - 1) + dfs01(n - 2); }

動態規劃

int dfs03(int n) {vec[maxn]vec[0] = 1;vec[1] = 2;int i;for (i = 2; i < n; i++){vec[i] = vec[i - 1] + vec[i - 2];}return vec[i-1]; }

矩陣快速冪

經典做法只要數一大就會超時,我們可以用矩陣快速冪進行優化,能將時間復雜度降到O(logN)
(如果全位輸出斐波那契數,貌似最大能算法到93,但是如果帶mod,那就可以算很大)
常用于求第n位斐波那契數的后x位(mod 10x

原理:

快速冪+矩陣
矩陣乘法:左矩陣的第一行乘以右矩陣的第一列(分別相乘),乘完后相加
單位矩陣: nn的矩陣 mat ( i , i )=1; 任何一個矩陣乘以單位矩陣就是它本身 n單位矩陣=n, 可以把單位矩陣等價為整數1。(單位矩陣用在矩陣快速冪中)

在斐波那契數列中:
f[n ] = 1 * f[n-1] + 1 * f [n - 2]
f[n-1] =1 * f[n-1] +0 * f [n - 2]
我們用矩陣來表示:

這就表示了斐波那契數列如何用矩陣來實現。

代碼:

#include <iostream> #include <cstddef> #include <cstring> #include <vector> using namespace std; typedef long long ll; const int mod=10000; typedef vector<ll> vec; typedef vector<vec> mat; mat mul(mat &a,mat &b) { mat c(a.size(),vec(b[0].size())); for(int i=0; i<2; i++) { for(int j=0; j<2; j++) { for(int k=0; k<2; k++) { c[i][j]+=a[i][k]*b[k][j]; c[i][j]%=mod; } } } return c; } mat pow(mat a,ll n) { mat res(a.size(),vec(a.size())); for(int i=0; i<a.size(); i++) res[i][i]=1;//單位矩陣; while(n) { if(n&1) res=mul(res,a); a=mul(a,a); n/=2; } return res; } ll solve(ll n) { mat a(2,vec(2)); a[0][0]=1; a[0][1]=1; a[1][0]=1; a[1][1]=0; a=pow(a,n); return a[0][1];//也可以是a[1][0]; } int main() { ll n; while(cin>>n&&n!=-1) { cout<<solve(n)<<endl; } return 0; } #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1000000007; struct matrix //定義結構體矩陣 {ll x[2][2]; } ; matrix mul(matrix a,matrix b) //矩陣乘法運算 {matrix ans;memset(ans.x,0,sizeof(ans.x));for(int i=0;i<2;i++) //三個循環表示兩個方陣相乘,可手動推寫一遍{for(int j=0;j<2;j++){for(int k=0;k<2;k++){ans.x[i][j]+=a.x[i][k]*b.x[k][j];ans.x[i][j]%=mod;}}}return ans; } matrix quickpow(matrix p,ll n) //矩陣快速冪,與快速冪道理方法相同 {matrix ans;for(int i=0;i<2;i++){for(int j=0;j<2;j++){if(i==j){ans.x[i][j]=1;} //一開始初始化他為單位陣else ans.x[i][j]=0;}}while(n)//快速冪{if(n&1){ans=mul(ans,p);}p=mul(p,p);n>>=1;}return ans; } int main() {matrix m;m={0,1,1,1}; ll n;cin>>n;ll ans1=0;matrix ans=quickpow(m,n-1);cout<<ans.x[1][1]<<endl; return 0; }

例題:

POJ 3070

模擬過程

如果數很大,比如求1000的斐波那契數列,矩陣快速冪也求不出來,那咋辦?
我們可以模擬斐波那契數列數列計算的過程,斐波那契數列的定義是f(n + 1) = f(n) + f(n - 1),我們可以手寫加減,模擬進行加減運算
例題 大菲波數
H DU - 1715

#include <iostream> #include <algorithm> #include <string> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> using namespace std; typedef long long ll; int main(){int n,q,i,j,temp=0;cin>>q;while(q--){cin>>n;char a[10010]="1",b[10010]="1",c[10010]={0};for(i=0;i<n-2;i++){int len=max(strlen(a),strlen(b));for(j=0;j<len;j++){ //模擬加法temp=0;if(a[j]>='0'){ //短的數不加temp+=a[j]-'0';}if(b[j]>='0'){temp+=b[j]-'0';}if(temp>=10){ //判斷進位if(c[j]>='0'){c[j]+=temp-10;}else{c[j]+=temp-10+'0';}c[j+1]=1+'0';}else{if(c[j]>='0'){if(temp==9){ //若前位進位了,而且加上的數字是9,那么還要進位!!!c[j]='0';c[j+1]='1';}else{c[j]+=temp;}}else{c[j]+=temp+'0';}}}strcpy(a, b);strcpy(b, c);memset(c, 0, sizeof(c));}int len=strlen(b);for(i=len-1;i>=0;i--){ //倒著輸出printf("%c",b[i]);}printf("\n");}return 0; }

總結

以上是生活随笔為你收集整理的斐波那契数列求法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。