有一种兔子,出生后一个月就可以长大,然后再过一个月一对长大的兔子就可以生育一对小兔子且以后每个月都能生育一对。现在,我们有一对刚出生的这种兔子,那么,n个月过后,我们会有多少对兔子呢?假设所有的兔子都不会死亡。
输入
输入文件仅一行,包含一个自然数n (1 <= n <= 50)。
输出
输出文件仅一行,包含一个自然数,即n个月后兔子的对数。
样例输入 Copy
5
样例输出 Copy
5
问题很简单,关键在于如何找到递推公式
第0个月 | 第1个月 | 第2个月 | 第3个月 | 第4个月 | |
大兔子 | 0 | 1 | 1 | 2 | 3 |
小兔子 | 1 | 0 | 1 | 1 | 2 |
假设第n个月的总兔子数为sum[n]。
那么那么第n个月的总兔子数其实分为两类,一类是大兔子的个数,一类是小兔子的个数
而我们其实仔细思考可以知道这样的关系:
第n个月的大兔子个数其实等于sum[n-1],理由是
第n-1个月的兔子,无论是大兔子还是小兔子,经过一个月后都是大兔子。
第n个月的小兔子个数其实等于sum[n-2],理由是第n个月的小兔子是第n-1个月的大兔子生的小兔子数,减去n-1个月的小兔子数长大的数量,再加上刚长大的大兔子所生的小兔子。
而此题的生育周期仅为1年,那么知道减去n-1个月的小兔子数长大的数量其实就等于刚长大的大兔子所生的小兔子数,即最后小兔子数就等于第n-1的大兔子个数,而我们只n-1的大兔子个数等于n-2的总兔子数,即sum[n-2]。
从而得出公式sum[n]=sum[n-1]+sum[n-2]。
代码实现
我觉得输出第五个月是8,但是答案的结果一直比我早一天,所以改为与题目相同的答案,要单独考虑n==2。
#include <stdio.h>
int main(){
int i,n,a[55];
scanf("%d",&n);
a[0]=1;
for (i=1;i<=n;i++){
if (i==1)a[i]=1;
else if (i==2)a[i]=2;
else if (i>2)a[i]=a[i-1]+a[i-2];
}
if (n==2)printf("%d\n",a[n]);
else printf("%d\n",a[n-1]);
return 0;
}
深入浅出学算法024-奶牛问题--递归C语言
Description
好好过个年吧,遇雪灾了, 好好火炬传递,遇藏独了 , 发展农村医疗吧,发手足口病了 买点股票吧,大小非减持了 做火车吧,还出轨了 在家待着吧,还地震了 天将降大运于斯国也,必先下其大雪,撞其火车,抢其火炬,震其国土,涨其物价,跌其股市,空房其民。
四川大地震,牵动了中华民族的很多颗心。
小明决定用实际行动来支援四川,所以他决定养奶牛给前线运牛奶。
最初他只有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
Input
输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0 < n < 55),n的含义如题目中描述。 n=0表示输入数据的结束,不做处理。
Output
对于每个测试实例,输出在第n年的时候母牛的数量。 每个输出占一行。
Sample Input
2
4
5
0
Sample Output
2
4
6
HINT
此题与之前的兔子繁殖很像。
在此我设第n年的奶牛数为sum[n]
思路如下:
同样,每年的奶牛总数可以分为大奶牛的个数加上小奶牛的个数。
第n个月的大奶牛个数其实等于sum[n-3](这里为何是3,可以自己草稿纸上画一下)
也就是说第n-3年前,无论大奶牛还是小奶牛,都长大成了大奶牛。
第n个月的小奶牛个数其实等于sum[n-1]
其实第n年的小奶牛应该等于第n-1年的大奶牛的个数(毕竟可以生小奶牛),和第n-1年小奶牛的个数(我们得知道这些小奶牛可能在第n年长大),减去在第n年长大的奶牛,再加上第n年长大的奶牛生的小奶牛(好巧不巧减去的等于加上的)。最终就等于sum[n-1]。
其实本道题与兔子繁殖问题思路一样,但不同的是生育周期不同。。
#include <stdio.h>
void sum(int n,long long a[]){
int i;
for (i=1;i<=n;i++){
if (i==1)a[1]=2;
else a[i]=a[i-1]*2+i;
}
printf("%d\n",a[n]);
}
int main()
{
long long a[100];
int n;
scanf("%d",&n);
sum(n,a);
return 0;
}
轻喷!!!!