1. 定義
斐波那契數列(fibonacci sequence),又稱**分割數列、因數學家列昂納多·斐波那契(leonardoda fibonacci)以兔子繁殖為例子而引入,故又稱為「兔子數列」,指的是這樣乙個數列:0、1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞迴的方法定義:f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2)(n≥2,n∈n*)。
2. 程式設計實現及演算法分析
要求:
編寫程式在控制台輸出斐波那契數列前20項,每輸出5個數換行。
方法1(遞迴呼叫)
public class fibonaccil
public static void fibonaccil_1(int n)
}private static int getfibo(int i)
}public class fibonaccil
public static void fibonaccil_2()
} }
此種方式缺點:大量迭代不斷消耗棧空間(搞web開發除錯維護的都應該知道伺服器棧資源的可貴,如果大量併發呼叫迭代導致伺服器棧資源遲遲得不到**,而導致web伺服器崩潰),效率底,函式自閉性比較弱(優秀的介面應該對輸入輸出可能出現的錯誤資訊進行捕捉,並提供清楚明了的處理結果),很容易出現錯誤,除錯困難,實際應用中一般不建議使用這種方式,使用時迭代次數也不能超過3次;
方法2(直接用遞推公式計算各項值,時間換空間):
public class fibonaccil
public static void fibonaccil_2(int n)
}private static int getfibo(int i)
}
方法3(方法2的改進,減少儲存變數):
public class fibonaccil
public static void fibonaccil_3(int n)}}
方法2和方法3主要使用於:使用場景一:對於物件或變數使用次數比較少,使用一次以後就不會再使用的場景;使用場景二:對於記憶體資源比較稀缺的實時性要求不是太高的嵌入式系統設計中多會採用此種方式;
方法4(空間換時間)
public static void fibonaccil_4(int n)
system.out.println("斐波那契數列的前20項如下所示:");
for (int i = 0; i < arr.length; i++)
}
此方法一般用於:物件或變數在程式執行的整個生命週期都存在或頻繁呼叫的場景,如呼叫外部webservice介面、抽象持續化層、常用配置檔案引數載入等等。
執行結果:
斐波那契數列的前20項為:
0 1 1 2 3
5 8 13 21 34
55 89 144 233 377
610 987 1597 2584 4181
total time in fibonaccil_3 : 2 ms
斐波那契數列前20項為:
0 1 1 2 3
5 8 13 21 34
55 89 144 233 377
610 987 1597 2584 4181
total time in fibonaccil_1 : 1 ms
0 1 1 2 3
5 8 13 21 34
55 89 144 233 377
610 987 1597 2584 4181
total time in fibonaccil_2 : 1 ms
斐波那契數列的前20項如下所示:
0 1 1 2 3
5 8 13 21 34
55 89 144 233 377
610 987 1597 2584 4181
total time in fibonaccil_4 : 0 ms
3. 相關數學
1、排列組合
有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?
這就是乙個斐波那契數列:登上第一級台階有一種登法;登上兩級台階,有兩種登法;登上**台階,有三種登法;登上四級台階,有五種登法……
1,2,3,5,8,13……所以,登上十級,有89種走法。
類似的,一枚均勻的硬幣擲10次,問不連續出現正面的可能情形有多少種?
答案是(1/√5)*=144種。
求遞推數列a⑴=1,a(n+1)=1+1/a(n)的通項公式
由數學歸納法可以得到:a(n)=f(n+1)/f(n),將斐波那契數列的通項式代入,化簡就得結果。
2、兔子繁殖問題
斐波那契數列又因數學家列昂納多·斐波那契以兔子繁殖為例子而引入,故又稱為「兔子數列」。
一般而言,兔子在出生兩個月後,就有繁殖能力,一對兔子每個月能生出一對小兔子來。如果所有兔子都不死,那麼一年以後可以繁殖多少對兔子?
我們不妨拿新出生的一對小兔子分析一下:
第乙個月小兔子沒有繁殖能力,所以還是一對
兩個月後,生下一對小兔對數共有兩對
三個月以後,老兔子又生下一對,因為小兔子還沒有繁殖能力,所以一共是三對
------
依次類推可以列出下表:
經過月數01
2345
6789
1011
12幼仔對數10
1123
581321
3455
89成兔對數01
1235
8132134
5589
144總體對數11
2358
1321
3455
89144
233
幼仔對數=前月成兔對數
成兔對數=前月成兔對數+前月幼仔對數
總體對數=本月成兔對數+本月幼仔對數
可以看出幼仔對數、成兔對數、總體對數都構成了乙個數列。這個數列有關十分明顯的特點,那是:前面相鄰兩項之和,構成了後一項。
這個數列是義大利中世紀數學家斐波那契在《算盤全書》中提出的,這個
級數 的通項公式,除了具有a(n+2)=an+a(n+1)的性質外,還可以證明通項公式為:an=(1/√5)*(n=1,2,3.....)
3、數列與矩陣
對於斐波那契數列1、1、2、3、5、8、13、……。有如下定義
f(n)=f(n-1)+f(n-2)
f(1)=1
f(2)=1
對於以下矩陣乘法
可見該矩陣的乘法完全符合斐波那契數列的定義
設矩陣迭代n-1次可以得到:
求f(n)等於求二階矩陣
a
的n - 1次方,結果取矩陣第一行第一列的元素。
這就是斐波那契數列的矩陣乘法定義。
另矩陣乘法的乙個運算法則a^n(n為偶數) = a^(n/2)* a^(n/2),這樣我們通過二分的思想,可以實現對數複雜度的矩陣相乘。
因此可以用遞迴的方法求得答案。
數列值的另一種求法:
f(n) = [ (( sqrt ( 5 ) + 1 ) / 2) ^ n ]
其中[ x ]表示取距離 x 最近的整數。
藍橋 BEGIN 4 Fibonacci數列
注意取模 用陣列儲存 避免超時 n的取值範圍 入門訓練 fibonacci數列 問題描述 fibonacci數列的遞推公式為 fn fn 1 fn 2,其中f1 f2 1。當n比較大時,fn也非常大,現在我們想知道,fn除以10007的餘數是多少。輸入格式 輸入包含乙個整數n。輸出格式 輸出一行,包...
藍橋 BEGIN4 Fibonacci數列
時間限制 1.0s 記憶體限制 256.0mb問題描述 fibonacci數列的遞推公式為 fn fn 1 fn 2,其中f1 f2 1。當n比較大時,fn也非常大,現在我們想知道,fn除以10007的餘數是多少。輸入格式 輸入包含乙個整數n。輸出格式 輸出一行,包含乙個整數,表示fn除以10007...
計算Fibonacci數列
上機內容 用動態分配空間的方法計算fibonacci數列的前30項並儲存到動態分配的空間中 上機目的 學習fibonacci數列演算法 我的程式 includeusing namespace std void main int p new int 30 p 1 p 1 1 cout p p 2 fo...