算法——递推算法(顺推、逆推)
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 |
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
运行结果
2. 逆推法
小龙的父亲供小龙4年(48个月)大学读书,采用整存零取的方式,一次性预存一笔钱于银行,小龙每个月月初取1000元。假设银行年利率为0.0171,若要求在第48个月小龙大学毕业时连本带息要取1000元,则应该一次性预存多少钱?
设每个月月末存款为,其中
表示月份,n=0时表示第一月的月初,数学模型为:
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
运行结果
不考虑利息,则须存48000元,由于利息的存在只需要存入47363元。关键取决于利息的大小,利息不大的情况下,可直接存入48000元,利息生出的钱可作为奖赏。
转载于:https://www.cnblogs.com/6DAN_HUST/archive/2011/07/25/2116308.html