斐波那契數列經典實例

斐波那契數列指的是這樣一個數列:1,1,2,3,5,8,13,21…… 

這個數列從第三項開始,每一項都等於前兩項之和。它的通項公式爲:(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}【√5表示根號5】

斐波那契數列按照其遞推公式可簡單寫出遞歸算法

int fib1(int n) {
    if(n == 1 || n == 2) 
        return 1;
    return fib1(n-1)+fib1(n-2);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

首先是數據範圍問題,用long型存儲結果數據與用int型同樣僅能計算到第46項,第47項開始數據溢出,即便用unsigned long也只能算到47而已。考慮使用字符模擬大整數運算的方法來處理。

其次的運算效率問題,第40項開始已經有明顯的等待時間,第46項需等待數秒才能算出結果。 
需考慮其他算法。

可以考慮簡單的動態規劃,開一個數組存儲計算過的數據,避免重複運算,可大幅提高效率(即空間換時間),效率接近線性。但遞歸算法當計算項數很大是會由於遞歸過深導致遞歸棧溢出。

直接開數組通過循環進行遞推運算可避免遞歸過深問題:

int fib2(int n, int f[]) {
    f[0] = f[1] = 1;
    for(int i = 2; i < n; i++) {
        f[i] = f[i-1] + f[i-2];
    }
    return f[n-1];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

但是數組難以存儲大數,用字符串數組存儲又過於浪費空間。

問題描述
  有一長度爲N(1<=N<=10)的地板,給定兩種不同瓷磚:一種長度爲1,另一種長度爲2,數目不限。要將這個長度爲N的地板鋪滿,一共有多少種不同的鋪法?
  例如,長度爲4的地面一共有如下5種鋪法:
  4=1+1+1+1
  4=2+1+1
  4=1+2+1
  4=1+1+2
  4=2+2
  編程用遞歸的方法求解上述問題。
輸入格式
  只有一個數N,代表地板的長度
輸出格式
  輸出一個數,代表所有不同的瓷磚鋪放方法的總數
樣例輸入
4
樣例輸出
         5
解題思路:有經驗的人一眼就看出這是一個斐波那契數列然後這題就解完了,但是像我一樣的初學者會有一個共同的疑問這題符合這個規律是 怎麼推出來的?
 無論給的長度是多少,我們只有兩種選擇要麼選1要麼選2假設給的長度是n,那麼選第一種剩下的長度就是n-1,
  選第二種剩下的長度就是n-2。以剩下的長度繼續選擇(n-1)-1和(n-1)-2,(n-2)-1和(n-2)-2之後以此類推
  所以此時n的方案數是長度爲n-1的方案數加上長度爲n-2的方案數
import java.util.Scanner;
public class Main {
  Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int [] arr = new int [n+1]; 
arr[0]=1;arr[1]=1;
for (int i = 2; i < arr.length; i++) {
arr[i] = arr[i-1] + arr[i-2];
}
System.out.println(arr[n]);
}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章