递归的应用

chencouage 2009-10-11 11:00:55
大家好,我今天面试遇到一道题:
假设有一种昆虫,从出生后第3年起每年(发育成熟了)都繁殖一只后代,昆虫后代长到第三年后也一样,每年又繁殖一只后代,假如所有昆虫的寿命固定为10年,问从第1只昆虫出生后的第N年,总共有多少只昆虫?请用c++编写求解函数.敬请大家探讨一下做法。最好用递归比较容易理解。
...全文
470 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
ProgrammerNO1 2009-10-24
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 linxinyuan 的回复:]
设S(n)为第n年的虫子总数;B(n)为第n年出生的虫子;D(n)为第n年死掉的虫子;则:
S(n)=S(n-1)+B(n-1)-D(n-1); n-1年的虫子总数,n-1年出生的虫子,n-1年死掉的虫子
D(n)=B(n-10); 第n年死掉的虫子=n-10年出生的虫子(n>10);else D(n) = 0
B(n)=S(n-1)-B(n-1)-B(n-2); 第n-1年的虫子总数-[n-1和n-2年出生的虫子](n>2);else B(n) = 0

注意边界就OK了
[/Quote]

有这样简单么
borefo 2009-10-24
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 linxinyuan 的回复:]
再次分析验证后的程序:思想一致
// 1.cpp : Defines the entry point for the console application.
//
/*
大家好,我今天面试遇到一道题:
假设有一种昆虫,从出生后第3年起每年(发育成熟了)都繁殖一只后代,昆虫后代长到第三年后也一样,每年又繁殖一只后代,假如所有昆虫的寿命固定为10年,问从第1只昆虫出生后的第N年,总共有多少只昆虫?请用c++编写求解函数.敬请大家探讨一下做法。最好用递归比较容易理解。
*/

假设虫虫都是在生完小虫虫后才死掉

#include "stdafx.h"

int S(int);
int B(int);
int D(int);

int S(int n)
{
if(n <3)
return 1;
else
return S(n-1)+B(n)-D(n);}

int B(int n)
{
if(n <3)
return 0;
else
return S(n-1)+D(n-1)-B(n-1)-B(n-2);}

int D(int n)
{
if(n <10)
return 0;
else if(n==10)
return 1;
else
return B(n-10);
}

int main(int argc, char* argv[])
{
printf("Hello World!\n");

printf("n = 1, f(n) = %d\n",S(1));
printf("n = 2, f(n) = %d\n",S(2));
printf("n = 3, f(n) = %d\n",S(3));
printf("n = 4, f(n) = %d\n",S(4));
printf("n = 5, f(n) = %d\n",S(5));
printf("n = 6, f(n) = %d\n",S(6));
printf("n = 7, f(n) = %d\n",S(7));
printf("n = 8, f(n) = %d\n",S(8));
printf("n = 9, f(n) = %d\n",S(9));
printf("n = 10, f(n) = %d\n",S(10));
printf("n = 11, f(n) = %d\n",S(11));
printf("n = 12, f(n) = %d\n",S(12));
printf("n = 13, f(n) = %d\n",S(13));
printf("n = 14, f(n) = %d\n",S(14));
printf("n = 15, f(n) = %d\n",S(15));
printf("n = 20, f(n) = %d\n",S(20));

return 0;
}

Hello World!
n = 1, f(n) = 1
n = 2, f(n) = 1
n = 3, f(n) = 2
n = 4, f(n) = 3
n = 5, f(n) = 4
n = 6, f(n) = 6
n = 7, f(n) = 9
n = 8, f(n) = 13
n = 9, f(n) = 19
n = 10, f(n) = 27
n = 11, f(n) = 40
n = 12, f(n) = 58
n = 13, f(n) = 84
n = 14, f(n) = 123
n = 15, f(n) = 179
n = 20, f(n) = 1169
Press any key to continue
[/Quote]

up一下
linxinyuan 2009-10-23
  • 打赏
  • 举报
回复
再次分析验证后的程序:思想一致
// 1.cpp : Defines the entry point for the console application.
//
/*
大家好,我今天面试遇到一道题:
假设有一种昆虫,从出生后第3年起每年(发育成熟了)都繁殖一只后代,昆虫后代长到第三年后也一样,每年又繁殖一只后代,假如所有昆虫的寿命固定为10年,问从第1只昆虫出生后的第N年,总共有多少只昆虫?请用c++编写求解函数.敬请大家探讨一下做法。最好用递归比较容易理解。
*/

假设虫虫都是在生完小虫虫后才死掉

#include "stdafx.h"

int S(int);
int B(int);
int D(int);

int S(int n)
{
if(n<3)
return 1;
else
return S(n-1)+B(n)-D(n);}

int B(int n)
{
if(n<3)
return 0;
else
return S(n-1)+D(n-1)-B(n-1)-B(n-2);}

int D(int n)
{
if(n<10)
return 0;
else if(n==10)
return 1;
else
return B(n-10);
}

int main(int argc, char* argv[])
{
printf("Hello World!\n");

printf("n = 1, f(n) = %d\n",S(1));
printf("n = 2, f(n) = %d\n",S(2));
printf("n = 3, f(n) = %d\n",S(3));
printf("n = 4, f(n) = %d\n",S(4));
printf("n = 5, f(n) = %d\n",S(5));
printf("n = 6, f(n) = %d\n",S(6));
printf("n = 7, f(n) = %d\n",S(7));
printf("n = 8, f(n) = %d\n",S(8));
printf("n = 9, f(n) = %d\n",S(9));
printf("n = 10, f(n) = %d\n",S(10));
printf("n = 11, f(n) = %d\n",S(11));
printf("n = 12, f(n) = %d\n",S(12));
printf("n = 13, f(n) = %d\n",S(13));
printf("n = 14, f(n) = %d\n",S(14));
printf("n = 15, f(n) = %d\n",S(15));
printf("n = 20, f(n) = %d\n",S(20));

return 0;
}

Hello World!
n = 1, f(n) = 1
n = 2, f(n) = 1
n = 3, f(n) = 2
n = 4, f(n) = 3
n = 5, f(n) = 4
n = 6, f(n) = 6
n = 7, f(n) = 9
n = 8, f(n) = 13
n = 9, f(n) = 19
n = 10, f(n) = 27
n = 11, f(n) = 40
n = 12, f(n) = 58
n = 13, f(n) = 84
n = 14, f(n) = 123
n = 15, f(n) = 179
n = 20, f(n) = 1169
Press any key to continue
linxinyuan 2009-10-23
  • 打赏
  • 举报
回复
测试程序:居于上述算法,稍微修改了一点
// 1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int S(int);
int B(int);
int D(int);

int S(int n)
{
if(n<3)
return 1;
else
return S(n-1)+B(n)-D(n);
}

int B(int n)
{
if(n<3)
return 0;
else
return S(n-1)-B(n-1)-B(n-2);
}

int D(int n)
{
if(n<10)
return 0;
else if (n < 13)
return 1;

else
return B(n-10);
}

int main(int argc, char* argv[])
{
printf("Hello World!\n");

printf("n = 0, f(n) = %d\n",S(0));
printf("n = 1, f(n) = %d\n",S(1));
printf("n = 2, f(n) = %d\n",S(2));
printf("n = 3, f(n) = %d\n",S(3));
printf("n = 4, f(n) = %d\n",S(4));
printf("n = 5, f(n) = %d\n",S(5));
printf("n = 6, f(n) = %d\n",S(6));
printf("n = 7, f(n) = %d\n",S(7));
printf("n = 8, f(n) = %d\n",S(8));
printf("n = 9, f(n) = %d\n",S(9));
printf("n = 10, f(n) = %d\n",S(10));
printf("n = 11, f(n) = %d\n",S(11));

printf("n = 12, f(n) = %d\n",S(12));
printf("n = 20, f(n) = %d\n",S(20));
printf("n = 50, f(n) = %d\n",S(50));

return 0;
}





Hello World!
n = 0, f(n) = 1
n = 1, f(n) = 1
n = 2, f(n) = 1
n = 3, f(n) = 2
n = 4, f(n) = 3
n = 5, f(n) = 4
n = 6, f(n) = 6
n = 7, f(n) = 9
n = 8, f(n) = 13
n = 9, f(n) = 19
n = 10, f(n) = 27
n = 11, f(n) = 38
n = 12, f(n) = 54
n = 20, f(n) = 1051
linxinyuan 2009-10-23
  • 打赏
  • 举报
回复
设S(n)为第n年的虫子总数;B(n)为第n年出生的虫子;D(n)为第n年死掉的虫子;则:
S(n)=S(n-1)+B(n-1)-D(n-1); n-1年的虫子总数,n-1年出生的虫子,n-1年死掉的虫子
D(n)=B(n-10); 第n年死掉的虫子=n-10年出生的虫子(n>10);else D(n) = 0
B(n)=S(n-1)-B(n-1)-B(n-2); 第n-1年的虫子总数-[n-1和n-2年出生的虫子](n>2);else B(n) = 0

注意边界就OK了
wulindl 2009-10-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 chencouage 的回复:]
大家好,我今天面试遇到一道题:
假设有一种昆虫,从出生后第3年起每年(发育成熟了)都繁殖一只后代,昆虫后代长到第三年后也一样,每年又繁殖一只后代,假如所有昆虫的寿命固定为10年,问从第1只昆虫出生后的第N年,总共有多少只昆虫?请用c++编写求解函数.敬请大家探讨一下做法。最好用递归比较容易理解。
[/Quote]
一只昆虫从出生到死亡可以繁殖的第一代后代为8个,设一全局变量为N,循环之N为止。
zhengjiankang 2009-10-21
  • 打赏
  • 举报
回复
有些算法恕在下不敢苟同。
对于这个问题,我有一个疑问,就是虫子在活到第10年临死之前是否还会繁殖下最后1个虫子才死亡。
下面是假设虫子在第10年还会繁殖1个虫子的分析过程:
先看一下前几年的虫子数:
年份 0 1 2 3 4 5 6 7
虫子 1 1 1 2 3 4 6 9
理由:虫子在出生后过3年才能繁殖,那么最开始就是第0年之后的虫子,要过3年也就是在第3年才能繁殖第一个虫子,在第4年和第5年的时候仍然只有这1个虫子能繁殖后代,到了第6年的时候,第3年繁殖出来的虫子能开始繁殖后代了。所以第6年比第5年多了2只虫子。。。
要求第N年的虫子数F(N),我们希望求出第N年出生的虫子数,然后他并不等于F(N)-F(N-1),因为F(N)-F(N-1)是虫子出生数与死亡数的差。
我们可以把第N年出生的虫子数记为S(N),有S(N)=0(N<0),S(N)=1(N=0),S(N)=S(N-3)+S(N-4)+S(N-5)+...+S(N-10);第N年死亡的虫子数记为D(N),则有D(N)=S(N-10);
于是我们有F(N)-F(N-1)=S(N)-D(N)。

代码如下:
C++ Code:
#include <iostream>

int S(int m)
{
if(m < 0)
return 0;
else if(m == 0)
return 1;
else
return S(m - 3) + S(m - 4) + S(m - 5) + S(m - 6) + S(m - 7) + S(m - 8) + S(m - 9) + S(m - 10);
}

int D(int n)
{
return S(n - 10);
}

int F(int k)
{
if(k < 0)
return 0;
else if(k == 0)
return 1;
else
return F(k - 1) + S(k) - D(k);
}

int main()
{
for(int i = 1; i < 15; i ++)
std::cout << F(i) << '\t';
std::cout << std::endl;

return 0;
}
showjim 2009-10-20
  • 打赏
  • 举报
回复
public static ulong insectBreeding(int N)
{
ulong value = 1;
if (N >= 3)
{
ulong dead = 0, count = 0;
ulong[] counts = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int y = 9; N > 0; N--)
{
dead += counts[y];//满10年的不繁殖并死亡
counts[y] = (count += counts[y >= 7 ? y - 7 : (y + 3)] - counts[y]);
value += count;
if (y == 0) y = 9;
else y--;
}
value -= dead;
}
return value;
}
  • 打赏
  • 举报
回复
mark,嗯,有些东西总是会想不起来,哎。
showjim 2009-10-20
  • 打赏
  • 举报
回复
        public static ulong insectBreeding(int N)
{
ulong value = 1;
if (N >= 3)
{
ulong dead = 0;
ulong[] count = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int e, s, y = 0; N > 0; N--)
{
dead += count[y = y == 0 ? 9 : (y - 1)];//满10年的不繁殖并死亡
count[y] = 0;
for (s = y >= 7 ? y - 7 : (y + 3), e = s + 7; s < e; s++)
{
count[y] += count[s > 9 ? s - 10 : s];
}
}
value = dead + count[0] + count[1] + count[2] + count[3] + count[4] + count[5] + count[6] + count[7] + count[8] + count[9];
}
return value;
}
帖子不能编辑 2009-10-20
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 xdxiaofeng 的回复:]
最后一版


int f(int n)
{

if(n== 0 || n==1)
{
return 1;
}

if(n <10)
{
return f(n-1)+f(n-2);
}
else if(n==10) //第10年第一只兔子死了
{
return f(n-1)+f(n-2)-1;
}
else
{
//每年多出来的兔子,在10年以后死掉
return f(n-1)+f(n-2) -(f(n-10)-f(n-11));
}
}
[/Quote]

错了,最后一个递归应该是
return f(n-1)+f(n-2) -2*(f(n-10)-f(n-11));

推理过程如下:
每一年的兔子都要分为两部分看待:一部分是新出生的,一部分是老兔子。
第n年的兔子就是第 n-1年新出生的兔子,加上2倍 第n-2年还不满8岁的老兔子。
为什么是两倍呢,因为只有这些兔子又生了小兔子。

第 n-1年薪出生的兔子为
f(n-1)-f(n-2)


第n年还没死的老兔子为
f(n-2)-(f(n-10)-f(n-11))
其中
f(n-10)-f(n-11)表示10年前出生的新兔子,今年应该死掉的。
f(n-2)-(f(n-10)-f(n-11))表示n-2年的兔子中去掉年龄大于10岁的兔子,也就是我们要的到了
第n年还没老死的兔子。

f(n-1)-f(n-2)
+2(f(n-2)-(f(n-10)-f(n-11)))
=f(n-1)+f(n-2) -2*(f(n-10)-f(n-11));
chencouage 2009-10-14
  • 打赏
  • 举报
回复
请问xdxiaofeng,当n >10时“return f(n-1)+f(n-2) -(f(n-10)-f(n-11));”中为什么要-(f(n-10)-f(n-11))呢?
帖子不能编辑 2009-10-14
  • 打赏
  • 举报
回复
最后一版


int f(int n)
{

if(n== 0 || n==1)
{
return 1;
}

if(n<10)
{
return f(n-1)+f(n-2);
}
else if(n==10) //第10年第一只兔子死了
{
return f(n-1)+f(n-2)-1;
}
else
{
//每年多出来的兔子,在10年以后死掉
return f(n-1)+f(n-2) -(f(n-10)-f(n-11));
}
}
帖子不能编辑 2009-10-14
  • 打赏
  • 举报
回复
有个边界条件判断错了,改正后如下:

int f(int n)
{
if(n== 0 || n==1)
{
return 1;
}

if(n<=10)
{
return f(n-1)+f(n-2)
}
else
{
return f(n-1)+f(n-2) -(f(n-10)-f(n-11));
}
}
帖子不能编辑 2009-10-14
  • 打赏
  • 举报
回复
int f(int n)
{
if(n== 0 || n==1)
{
return 1;
}

if(n<10)
{
return f(n-1)+f(n-2)
}
else
{
return f(n-1)+f(n-2) -(f(n-10)-f(n-11));
}
}
24K純帥 2009-10-14
  • 打赏
  • 举报
回复
类似于斐波那契。。
帖子不能编辑 2009-10-14
  • 打赏
  • 举报
回复


每年多出来的兔子,在10年以后死掉
比如说,1,1,2,3,5,8,13,21,34,
这几个数,后面是第10年的兔子,如果兔子都不会死的话是
55,
可是现在第一年出生的兔子有10岁了,所以它在第10年死掉。
现在变成54。

再来看下一个数,原来是88,现在第二年出生的兔子有10岁了,他们应该死掉。
在看下下一个数,原来是142, 第三年出生的兔子要在这个时候死掉,第三年出生了一只兔子,所以减1。

现在的兔子数列变为
1,1,2,3,5,8,13,21,34,54,88,141


f(n-10)-f(n-11) 就死n-10年新出生的兔子数目。


绿色夹克衫 2009-10-13
  • 打赏
  • 举报
回复
简单写了一个递推的,LZ帮忙验证一下是否算对了?

using System;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
long[] count = new long[n];
count[0] = count[1] = 1;

for (int i = 2; i < n; i++)
{
if (i < 12)
{
if (i == 10)
count[i] = count[i - 1] + count[i - 2] - 2 * count[i - 10];
else
count[i] = count[i - 1] + count[i - 2];
}
else
count[i] = count[i - 1] + count[i - 2] - 2 * count[i - 12];
}

Console.WriteLine(count[n - 1]);
}
}
}
chencouage 2009-10-13
  • 打赏
  • 举报
回复
与兔子繁殖问题类似,但是还有一个条件寿命固定为10年。
小坏猪猪 2009-10-12
  • 打赏
  • 举报
回复
3楼的算法是对的,但是n=10和n<10的一样,因为固定寿命是10年
f(N)=f(N-1)+f(N-2), f(1)=f(2)=1; N <=10
f(N)=f(N-1)+f(N-2)-f(N-10); N>10
加载更多回复(14)

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧