微信扫一扫打赏支持

递推1--兔子问题

递推1--兔子问题

一、心得

推出部分实例

仔细分析递推公式,递推公式如果印合实例,那就对了

有了递推公式,编程很简单。

当xyz都是1的时候,f(n)=f(n-1)+f(n-2)

 仔细分析,想清楚了就好,想清楚了,就简单了

二、题目代码及结果

 1 /*
 2 有一对小兔子,小兔子过Z个月长大,一对大兔子X个月生Y对小兔子,求n个月后的兔子总对数。
 3 
 4 问题一: 
 5 有一对小兔子,小兔子过5个月长大,一对大兔子3个月生4对小兔子,求n个月后的兔子总对数。
 6 f(n)表示n个月后的兔子总数
 7 f(n)=n那个月原有的兔子+n那个月新生的兔子
 8 n那个月原有的兔子是:f(n-1)
 9 n那个月新生的兔子是:n-x那个月成熟的兔子,也就是n-x-z那个月所有的兔子,因为n-x-z那个月所有的兔子在n-x那个月的时候都成熟了 
10 
11 故f(n)= f(n-1)+ f(n-x-z)*(y/x);这里必须是*(y/x),这是每个月生产的。 
12 
13 这个表达式也适合于一个月生一对的情况;
14 一个月的情况可以看成成熟+不成熟,和原来的+新生的。而多个月的情况看成后一种比较好,因为看成前一种会超级麻烦。
15 
16 到本题,也就是f(n)= f(n-1)+ f(n-x-z)*y;也就是f(n)= f(n-1)+ f(n-8)*(4/3);
17 
18 问题二: 
19 有一对小兔子,小兔子过5个月长大,一对大兔子3个月生4对小兔子,求n个月后的大兔子总对数。
20 用f(n)表示大兔子,那么
21 f(n)= 上个月的大兔子数+这个月新长成的大兔子数 
22 上个月的大兔子数是:f(n-1)
23 这个月新长成的大兔子数是:因为兔子需要5个月长大,所以应该是n-5个月那个月的新出生的兔子, 
24 n-5个月那个月的新出生的兔子是n-5-3那个月的所有大兔子数,因为大兔子经过三个月才能下崽崽, 
25 故f(n)=f(n-1)+f(n-5-3)*(4/3); 
26 其实因为我把它看成每月生产(4/3)对兔子,所以不需要再减3 
27 */
28 #include <iostream>
29 using namespace std;
30 //前八个月的兔子总对数都是一对,initTotalRabbit[1]表示第一个月 
31 double initTotalRabbit[9]={0,1,1,1,1,1,2.3333,3.6667,5};
32 double calcTotalRabbit(int n){
33     if(n<=8)
34         return initTotalRabbit[n];
35     else
36         return calcTotalRabbit(n-1)+ calcTotalRabbit(n-8)*(4.0/3);
37 } 
38 
39 //前五个月的大兔子数目为0,initBigRabbit[1]表示第一个月的大兔子数目
40 double initBigRabbit[9]={0,0,0,0,0,0,1,1,1};
41 double calcBigRabbit(int n){
42     if(n<=8)
43         return initBigRabbit[n];
44     else
45         return calcBigRabbit(n-1)+ calcBigRabbit(n-5)*(4.0/3);
46 } 
47 int main(){
48     for(int i=1;i<=20;i++){
49         double total=calcTotalRabbit(i);
50         double big=calcBigRabbit(i);
51         printf("月份:%3d    兔子总对数:%6.2lf    大兔子对数:%6.2lf    小兔子对数:%6.2lf\n",i,total,big,total-big);
52     }
53     
54     return 0;
55 }

 

posted @ 2017-06-11 10:05  范仁义  阅读(615)  评论(0编辑  收藏  举报