递推推算法使用“稳扎稳打”的策略,不断利用已有的信息推导出新的东西。具体来说有如下两种:
(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]);
}
}