Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
一对成熟的兔子每天能且只能产下一对小兔子,每次都生一公一母,每只小兔子的成熟期是1天,小兔子出生后隔一天才能再生小兔子。第一天某人领养了一对成熟的兔子,一公一母,请问第N天以后,他将会得到多少对兔子。
Input
测试数据包括多组,每组一行,为整数n(1≤n≤90)。
输入以0结束。
Output
对应输出第n天有几对兔子(假设没有兔子死亡现象,而且是一夫一妻制)。
Sample Input
1
2
0
Sample Output
1
2
Hint
数据类型可以用64位整数:long long
Source
majia
本题是典型的递推,我们已经知道第一天的兔子数,我们就能推出第二天的兔子数,进而推出第三天,第四天……
逆向递归也一样,要想知道第“n”天的兔子数只要知道“n-1”天的兔子数就可以,要知道“n-1”天,只要知道“n-2”天就可以…… n无论是几总能减到“1”,即第一天的兔子数,再一级一级返回去
递推和递归思路相通,有时可以通用
递归一定要注意递归的结束标志,本题就是“n”为“1”时地推结束
兔子数随天数的变化:1, 2, 3,5, 8……
所以我们可以看出,从第三天起每一天是前两天的和,因此递推方程为a[n] = a[n-1] + a[n-2], (n>1)
递推:
#include <stdio.h>
int main()
{
long long a[90];
a[0] = 1;
a[1] = 2;
int n,i;
while(scanf("%d",&n)&&n)
{
for(i=2;i<n;i++) //递推到第“n”天;
{
a[i] = a[i-1] + a[i-2];
}
printf("%lld\n",a[n-1]);
}
return 0;
}
递归:
但是本题递归费时间太长,在规定的时间内跑不完,所以我们用以个数组存储先前已经算出的数据,那在后面就不用再计算了,这样就节约下了很多时间
#include <stdio.h>
#include <stdlib.h>
long long a[90] = {0};
//要定义为longlong型,当“n”接近“90”时,结果便超出int的范围了;
long long f(int n)
{
if(a[n-1]!=0) return a[n-1]; //a[n-1]不为零,即先前已经计算出了结果;
else return a[n-1] = (f(n-1) + f(n-2));
}
int main()
{
a[0] = 1;
a[1] = 2;
int n;
long long sum;
while(scanf("%d",&n)&&n)
{
sum = f(n);
printf("%lld\n",sum);
}
return 0;
}