1. 程式人生 > >【演算法】Fibonacci解法總結

【演算法】Fibonacci解法總結

我這裡說的Fibonacci數列不僅僅是f(n-1) + f(n-2)的情況,也可以是f(n-1) + f(n-2) + … + f(n-k)的情況。但是這裡我們用f(n-1) + f(n-2)來進行討論,簡化理解,舉一反三。

解法一,遞迴

實現非常簡單。

int fibonacci(int i){
    if(i==0){
      return 0;
    }else if(i==1){
      return 1;
    }else {
      return fibonacci(i-1)+fibonacci(i-2);
    }
  }
}

解法二,動態規劃

核心程式碼如下:

    long array[]=new long [n+1];
    array[0]=0;
    array[1]=1;
    for(int i=2;i<n+1;i++){
      array[i]=array[i-1]+array[i-2];
    }

這種解法與遞迴解法相比,具有非常大的效能提升。

解法三,動歸優化

將空間優化到O(1):

int fib(int n) {  
    int last, nextToLast, answer = 0;  
    if (n <= 1) {  
        return
1; } last = nextToLast = 1; for (int i = 0; i < n; i++) { //f(n)=f(n-1)+f(n-2) answer = last + nextToLast; //f(n-2)=f(n-1) nextToLast = last; //f(n-1)=f(n) last = answer; } return answer; }

解法四,特殊解法

這種解法可以將時間複雜度優化到O(logn),牛客網的左老師書上講的非常清楚,這裡直接藉助過來以供參考:

/*
下面介紹一種時間複雜度是O(logn)的方法:

對於斐波那契數列1,1,2,3,5,8,13…….有如下定義:

F( n ) = F( n-1 ) + F( n-2 )
F( 1 ) = 1
F( 2 ) = 1

矩陣形式:

[ F( n+1 ) ,  F( n ) ] = [ F( n ) , F( n-1 ) ] * Q  其中 [ F( n+1 ) ,  F( n ) ]為行向量,Q = { [ 1, 1 ]; [ 1, 0 ] }為矩陣

則 [ F( n+1 ) , F( n ) ]=[ 1 , 0 ] * Qn , 
*/

struct Matrix    
{          
       long long m_00, m_01, m_10, m_11;   
   Matrix ( long long m00 = 0,  long long m01 = 0,  long long m10 = 0,   long long m11 = 0 )    
       :m_00( m00 ), m_01( m01 ), m_10( m10 ), m_11( m11 )     
       {    
       }    
};


Matrix MatrixMultiply (  const Matrix & m1, const Matrix & m2    )    
{  
  long long m00 = m1.m_00 * m2.m_00 + m1.m_01 * m2.m_10;
  long long m01 = m1.m_00 * m2.m_01 + m1.m_01 * m2.m_11; 
  long long m10 = m1.m_10 * m2.m_00 + m1.m_11 * m2.m_10    
  long long m11 = m1.m_10 * m2.m_01 + m1.m_11 * m2.m_11; 
      return Matrix ( m00,  m01,  m10, m11 );    
}

Matrix MatrixPower( unsigned int n )    
{    
       assert(n > 0);    
       Matrix m;    
       if( n == 1)    
       {    
             m = Matrix(1, 1, 1, 0);    
       }    
      else if(n % 2 == 0)    
       {    
             m = MatrixPower( n / 2 );    
             m = MatrixMultiply( matrix, matrix );    
       }    
      else if( n % 2 == 1 )    
       {    
             m = MatrixPower( (n - 1) / 2 );    
             m = MatrixMultiply( m, m );    
             m = MatrixMultiply( m, Matrix( 1, 1, 1, 0 ) );    
       }     
      return m;    
}  
long long Fibonacci( unsigned int n )
{
      int result[2] = { 0, 1 };
      if( n < 2 )
            return result[ n ];

      Matrix Q = MatrixPower( n - 1 );  //注意:按定義式應該用[ 1, 0 ]*Q, 或者等價於{ [ 1 , 0 ]; [ 0, 0 ] }*Q, 但是因為顯然結果相同,所以略去這一步。
      return Q.m_00;
}

總結

我覺得Fibonacci數列對於理解動態規劃也是非常重要,動態規劃的本質就是在遞迴中優化而來的。
Fibonacci問題還可以用來解上臺階問題硬幣面值組合問題

相關推薦

演算法Fibonacci解法總結

我這裡說的Fibonacci數列不僅僅是f(n-1) + f(n-2)的情況,也可以是f(n-1) + f(n-2) + … + f(n-k)的情況。但是這裡我們用f(n-1) + f(n-2)來進行討論,簡化理解,舉一反三。 解法一,遞迴 實現非常簡單

12、演算法查詢演算法總結

一、順序查詢 1、定義     順序查詢屬於無序查詢,從資料結構的一端開始,順序掃描,依次將掃描到的節點關鍵字與給定值K相比,若相等,則表示查詢成功,若掃描結束,仍未找到關鍵字與給定值K相等,則表示查詢失敗。 時間複雜度分析     查詢成功時:平均查詢長度為(N+1)/2   

11、演算法排序演算法總結

常見排序演算法總結 一、氣泡排序 1、定義     氣泡排序是一種比較簡單的排序演算法,它會遍歷若干次要排序的數列,每次便利時,它都會從前往後依次的比較兩個相鄰的數的大小;如果前者比後者大,則交換它們的位置。     這樣一次遍歷之後,最大的元素就在數列的末尾了。採用相同的方法在

演算法最大的Fibonacci

最大的Fibonacci數   無窮數列1,1,2,3,5,8,13,21,34,55…稱為Fibonacci數列,它可以遞迴地定義為 F(n)=1 ………..(n=1或n=2) F(n)=F(n-1)+F(n-2)…..(n>2) 現要你來求第n個斐波納奇數。(

演算法演算法知識點總結

## 專案知識點評估:1、fm + ffm + lr   # fm 相比 lr 引進了特徵組合(二次項)   # fm 解決了資料稀疏性導致的引數訓練不充分問題(尤其對於one-hot編碼之後)   # ffm 增加了field,隱向量不僅與特徵相關,也與field相關  

演算法最大似然估計總結筆記

最大似然估計學習總結------MadTurtle 1. 作用 在已知試驗結果(即是樣本)的情況下,用來估計滿足這些樣本分佈的引數,把可能性最大的那個引數作為真實的引數估計。 2. 離散型 設為離散型隨機變數,為多維引數向量,如果隨機變數相互獨立且概率計算式為P{,則可得概率函式為P{}=,在固定時,上式

演算法最近點對問題(暴力破解法

簡單的畫了一張圖: 通過暴力方式,進行一次比較獲取兩個點之間的最短距離: //點對最近問題(暴力破解法) #include<iostream> #include<cmath> using namespace std; doub

資料結構與演算法揹包問題總結梳理

# 揹包問題總結分析 揹包問題是個很經典的動態規劃問題,本部落格對揹包問題及其常見變種的解法和思路進行總結分析 ## 01揹包 #### 問題介紹 有 N 件物品和一個容量是 V 的揹包。每件物品只能使用一次。 第 i 件物品的體積是 v[i],價值是 w[i]。 求解將哪些物品裝入揹包,

Java日誌知識總結和經常使用組合配置(commons-logging,log4j,slf4j,logback)

ng- binder mono leading black auto erb param 1.2 Log4j Apache的一個開放源碼項目,通過使用Log4j,我們能夠控制日誌信息輸送的目的地是控制臺、文件、GUI組件、甚至是套接口服務 器

雜文2017年度總結

導讀 付出 結束 分享圖片 轉折 tps 天都 新人 自己 導讀 在2017年的尾巴,回顧過去一整年,有些成長收獲,有些失落惆悵;好的壞的,經歷過的,都需要重溫,算是對2017年的正式告別。 回顧 過去看現在 在2016年度總結中,有對2017年的展望。 技術書籍的

評分Beta 答辯總結

mage www. www nan -s 好的 ext html 6.5 【評分】Beta 答辯總結 總結 按時交 - 有分 晚交 - 0分 遲交一周以上 - 倒扣本次作業分數 抄襲 - 倒扣本次作業分數 由於前期不夠重視,到beta評分才發現有5組的代碼提交僅由

PHP面試總結

tar htm itl body .cn clas tps html ref 文章出處:https://www.cnblogs.com/codetao/p/6418127.html【轉】PHP面試總結

轉載CPU相關總結

case total 總結 touch ads socket RM Oday side What is the difference between Processor, Core, Logical Processor ? Processor : It’s the ph

MySQL簡單命令總結

MySQL查看數據庫 SHOW DATABASES; 創建數據庫 CREATE DATABASE IF NOT EXISTS 數據庫名; 選擇數據庫 USE 數據庫名; 查看數據庫中的數據表 SHOW TABLES; 刪除數據庫 DROP DATABASE IF EXISTS 數據庫名; 創建一個簡單的數據庫

HDU1848Fibonacci again and again(博弈論)

spa sync splay turn pro [1] 斐波那契 play cci 【HDU1848】Fibonacci again and again(博弈論) 題面 Hdu 你有三堆石子,每堆石子的個數是\(n,m,p\),你每次可以從一堆石子中取走斐波那契數列中一個元

POJ3070Fibonacci

題意 求Fibn mod m的值 m=10000,0<=0<=2*109 分析 矩陣快速冪模板 設f(n)={Fibn,Fibn+1},可得到單位矩陣為{(0,1)(1,1) } 程式碼 #include<iostream> #include<cstdio&

演算法字串迴圈移位後是否包含

問題 給定兩個字串s1和s2,要求判斷s2是否能夠被通過s1做迴圈移位(rotate)得到的字串包含。 例如,s1=AABCD和s2=CDAA,返回true;給定s1=ABCD和s2=ACBD,返回false。 解法一 最直接最笨的方法就對s1進行迴圈移動,再

13、演算法演算法複雜度分析

一、演算法的時間複雜度分析 1、時間複雜度的定義     在進行演算法分析時,演算法中基本操作語句重複執行的次數是問題規模n的某個函式,用T(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函式,

演算法第三章作業 實踐報告

【演算法】實踐第三章作業 1. 實踐題目  最大子段和  2. 問題描述 給定n個整數(可能為負數)組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。當所給的整數均為負數時,定義子段和為0。

演算法-003 三次貝塞爾曲線的交點

【演算法】-003 三次貝塞爾曲線的交點   最近在工作中遇到一個問題,想通過計算兩條三次貝塞爾曲線的交點位置。嘗試了列舉法之後覺得計算速度太慢,於是來找其他演算法。 文章目錄 【演算法】-003 三次貝塞爾曲線的交點 1、 列舉法求貝塞爾曲線交