個人理解的遞推思想:通過遞推的條件,從第一層或最後一層將剩餘推導出來,擴展進階開來像是動態規劃。
遞推推算法使用“穩紮穩打”的策略,不斷利用已有的信息推導出新的東西。具體來說有如下兩種:
(1)順推法: 是指從已知條件出發,逐步推算出要解決問題的方法。例如斐波那契數列
就可以通過順推法不斷遞推算後新的數據。
(2) 逆推法: 是從己知的結果出發,用迭代表達式逐步誰算出問題開始的條作,即順推
法的道過程斐波那契數列 (順推法)
斐波那契數列因是由數學家列昂納多*斐波那契以免子繁殖爲例子而引入的,故又稱爲“ 免子數列”。一般而言,免子在出生兩個月後,就有繁殖能力,一對兔子每個月能生出一對小兔子來。如果所有兔子都不死,那麼一對兔子一年內能繁殖成多少對兔子?
算法分析: 我們不妨拿新出生的一對小兔子進行如下分析:
(1)第一個月小兔子沒有繁殖能力,所以還是一對;
(2) 兩個月後,生下一對小兔,總數共有兩對;
(3) 3 個月以後,老兔子又生下一對,因爲小兔子還沒有繁殖能力,所以一共是3 對:....................
依此類推可以得出如下數據:
經過月-1-2-3-4-5-6-7-8-9-10-11-12-
免子對數:--1-2--3---5--8--13-21--34--55--88--144--233
每個月所呈現的兔子個數1,2,3,5,8構成了一個數列。這個數列有着十分明顯的特點,即前面相鄰兩項之和構成了後一項。上述特點的證明。每月的大兔子數爲上月的兔子數,每月的小免了數爲上月的大兔子數,即上上月的兔子數,即每月的兔子數爲上月的兔子數與上上月免子數相加的和。
具體算法:
設置初始值爲F0=1,第一個月兔子的總數是F1=1
第2個月的免子總數是F2=F0+F1;
第3 個月的兔子總數是F3=F1+F2;
第4個月的兔子總數是F4=F2+F3;
.................
第n個月的兔子總數爲Fn=Fn-2+Fn-1;
- #include<stdio.h>
- #define NUM 13
- void main()
- {
- int i;
- long fib[NUM]={1,1};
- for(i=2;i<NUM;i++){
- fib[i]=fib[i-1]+fib[i-2];
- }
- for(i=0;i<NUM;i++){
- printf("%d月兔子總數:%d\n",i,fib[i]);
- }
- }
斐波那契數列 (逆推法)
母親爲兒子小Sun的4年大學準備了4年大學準備了一筆存款,方式是整存零取,規定小SUN每月月底取下一個月的生活費1000元。現在假設銀行的年利息爲1.71%,請計算母親最少需要存入多少錢?
算法分析:
可以採用逆推法分析存錢和取錢的過程,因爲按照月爲週期來取錢,所以將4年分爲48個月,並分別對每個月進行計算。
(1) 如果在第48 個月後Sum 大學畢業時連本帶息要取1000元,則要先要求處第47個月時的銀行存款的錢數:第47 個月月末存款=1000/(1+0.0171/12);
第46 個月末存數=(第47 個月月末存+1000)/(1+0.0171/12);
第45 個月月末存款=(第46 個月月末存款+1000)/(1+0.0171/12);
......
第2 個月月末存款=(第3 個月月末存款+1000/(1+0.0171/12)
第1個月月末存款=(第2 個月月術存款+1000)/(1+0.0171/12)
- #include<stdio.h>
- #define FETCH 1000
- #define RATE 0.0171
- void main()
- {
- double corpus[49];
- int i;
- corpus[48]=(double)FETCH;
- for(i=47;i>0;i--){
- corpus[i]=(corpus[i+1]+FETCH)/(1+RATE/12);
- }
- for(i=48;i>0;i--){
- printf("第%d月末本利合計:%.2f\n",i,corpus[i]);
- }
- }