算法——递推算法(顺推、逆推)

1. 顺推法

斐波拉契的“养兔问题

公元1202年,一位意大利比萨的商人斐波拉契(Fibonacci,约1170-1250?)在他的《算盘全书》(这里的“算盘”指的是计算用沙盘)中提出过一个“养兔问题”。

某人买回一对小兔,一个月后小兔长成大兔。再过一个月,大兔生了一对小兔,以后,每对大兔每月都生一对小兔,小兔一个月后长成大兔。如此下去,问一年后此人共有多少对兔子?

表1 兔子的繁殖过程

月份

大兔数量

1月大的

小兔数量

2月大的

小兔数量

兔子总数

初始状态

0

1

0

1

1月

0

0

1

1

2月

1

1

0

2

3月

1

1

1

3

4月

2

2

1

5

5月

3

3

2

8

6月

5

5

3

13

7月

8

8

5

21

8月

13

13

8

34

9月

21

21

13

55

10月

34

34

21

89

11月

55

55

34

144

12月

89

89

55

233

clip_image002为第n个月份的兔子总数,数学模型:

clip_image004

clip_image006

 

C#代码实现            int months = 12;    //设定月份

            int[] rabbitNum = new int[months+1];

            //设定初始状态
            rabbitNum[0] = 1;    
            rabbitNum[1] = 1;

            for (int i = 2; i <= months; i++)
            {
                rabbitNum[i] = rabbitNum[i - 1] + rabbitNum[i - 2];
            }

            for (int i = 0; i <= months; i++)
            {
                Console.WriteLine(i + "月的兔子总数为: " + rabbitNum[i]);
            }

 

Matlab代码实现%斐波拉契的养兔问题
clear,close all

format short;
%设定月份
months=12;

rabbitNum=zeros(months+1);

%设定初始状态
rabbitNum(1)=1;
rabbitNum(2)=1;

for i=3:months+1
    rabbitNum(i)=rabbitNum(i-1)+rabbitNum(i-2);
end

for i=1:months+1
    fprintf('%d 月的兔子总数为: %d\n',i-1,rabbitNum(i));
end

 

运行结果

clip_image008

 

2. 逆推法

小龙的父亲供小龙4年(48个月)大学读书,采用整存零取的方式,一次性预存一笔钱于银行,小龙每个月月初取1000元。假设银行年利率为0.0171,若要求在第48个月小龙大学毕业时连本带息要取1000元,则应该一次性预存多少钱?

设每个月月末存款为clip_image002[1],其中clip_image011表示月份,n=0时表示第一月的月初,数学模型为:

clip_image013

clip_image015

 

C#代码实现            double monthRate = 0.0171 / 12;
            int months = 49;
            int FETCH = 1000;

            double[] money = new double[months];

            money[48] = FETCH;
            for (int i = months-1; i > 0; i--)
            {
                money[i - 1] = money[i] / (1 + monthRate) + FETCH;
            }

            for (int i = months-1; i >= 0; i--)
            {
                Console.WriteLine(""+i+"个月份的月末存款为: " + money[i] );
            }

 

Matlab代码实现%存款问题
clear,close all

monthRate=0.0171/12;

months=49;
Fetch=1000;

Money=zeros(months);
Money(49)=Fetch;

for i=months:-1:2
    Money(i-1)=Money(i)/(1+monthRate)+Fetch;
end

for i=months:-1:0
    fprintf('第 %d 个月份的月末存款为: %f\n',i,Money(i+1));
end

 

运行结果

clip_image017

不考虑利息,则须存48000元,由于利息的存在只需要存入47363元。关键取决于利息的大小,利息不大的情况下,可直接存入48000元,利息生出的钱可作为奖赏。

转载于:https://www.cnblogs.com/6DAN_HUST/archive/2011/07/25/2116308.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值