兔子繁殖问题与解决方案
一、兔子繁殖问题
问题描述:
兔子永远不死;
兔子出生后,两个月(即从它生命中的第三个月开始)达到性成熟;
兔子总是雌雄成对出生。每个月月初,每对性成熟的兔子正好生一对小兔;
计算第n个月的兔子数——rabbit(n)。
二、问题分解
rabbit(n)正好是第n个月之前活着的兔子数与第n个月月初出生的兔子数之和。在第n个月月初前,有rabbit(n-1)对兔子数,同时那些在第n-2个月活着的兔子在第n个月月初准备生产,即第n个月月初出生的兔子数是rabbit(n-2)。因此有递归关系式:
rabbit(n)=rabbit(n-1)+rabbit(n-2) -----(A)
三、递归方法
根据实际问题,设置两个基本事件:rabbit(1)=1和rabbit(2)=1,由此,递归定义式为:
rabbit(n)=1when n=1 or n=2;
rabbit(n)=rabbit(n-1)+rabbit(n-2)when n>2;
rabbit(1),rabbit(2),rabbit(3),... ... 称为Fibonacci序列,它是许多自然现象的模型。
rabbit(n)的Java方法:
[java]view plaincopy
publicstaticint rabbit(int n){
//------------------------------------------
//Computes a term in the Fibonacci sequence
//Precondition:n is a positive integer
//Postcondition:Returns the nth Fibonacci number
//------------------------------------------
if(n<=2){return1;}
else {//n>2, so n-1>0 and n-2>0
return rabbit(n-1)+rabbit(n-2);
}//end if
}//end rabbit
四、迭代方法
rabbit的递归解决方案本身效率很低,当n相当大时,许多值可能重复计算上亿次。迭代解决方案用向前推替代向后推,并且每个值只计算一次,即使n非常大也可以计算,其Java方法如下:
[java]view plaincopy
staticint iterativeRabbit(int n){
//Iterative solution to the rabbit problem.
//initialize base cases:
int previous=1; //initially rabbit(1)
int current=1; //initially rabbit(2)
int next=1; //result when n is 1 or 2
//compute next rabbit values when n>=3
for(int i=1;i<=n;i++){
//current is rabbit(i-1),previous is rabbit(i-2)
next=current+previous; //rabbit(i)
previous=current; //get ready for
current=next; //next iteration
}
return next;
}//end iterativeRabbit