递推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 }