昆虫繁殖(继续理解递推和递归)
/*【题目描述】
科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。
每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。
假设每个成虫不死,第一个月只有一对成虫,
且卵长成成虫后的第一个月不产卵(过X个月产卵),问过Z个月以后,共有成虫多少对?
0≤X≤20, 1≤Y≤20, X≤Z≤50。
【输入】
x, y, z的数值。
【输出】
过Z个月以后,共有成虫对数。
【输入样例】
1 2 8
【输出样例】
37
*/
/*
分析:
设a数组为每月的成虫数
b数组为每月的卵数
则可以写出下面的式子
a[i]=a[i-1]+b[i-2] //注意:是i-2
b[i]=y*a[i-x]
*/
方法一:递推
#include <iostream>
using namespace std;
#include <cstdio>
int a[25], b[25];
void fun(int x,int y,int z)
{
a[1] = 1; b[1] = 0;
for (int i = 1; i <= x; i++)
{
a[i] = 1;
b[i] = 0;
}
for (int i = x + 1; i <= z+1; i++) //过了z个月,所以是z+1
{//递推式:
a[i] = a[i - 1] + b[i - 2];
b[i] = a[i - x] * y; //从卵变为成虫时间不计
}
cout << a[z+1];
}
int main()
{
int x, y, z;
cin >> x >> y >> z;
fun(x,y,z);
}
方法二:递归
#include <iostream>
using namespace std;
#include <cstdio>
int a[25], b[25],x,y,z;
/*
说明:z>=x+2的递归式子是由两个递推式子联立解出的,fun函数作为一个
功能单元来计算z个月以后的成虫数。
另外,只要写的出递推式,就能用递推算,也一定能用递归来计算。
因为递推/递归式本身就是用来说明前几个和后几个待求项的关系的,所以正着算
或者倒着算都是可行的。
*/
int fun(int z)
{
if (z < x+2) return 1; //注意这里是过了x个月,所以不能取等
if(z>=x+2) return (fun(z-1)+fun(z-x-2)*y);
}
int main()
{
cin >> x >> y >> z;
cout<<fun(z);
}
关于递推和递归的理解的补充:
1.首先,两者都是对关于前几项和后几项的关系式的描述,是两种解决问题的不同思想,只不过:递推正着描述,递归倒着描述。而“倒着描述”——递归的实现往往需要借助“功能单元”,这就是为什么在写递归时需要考虑一个相同的功能单元。所以在解决有些问题时考虑用 “把一个问题分解成相同类型的子问题” 的想法会帮助你找到递推/归关系式或者是递归的具体做法。
2.有时候一个问题解决的递推/递归式子递推不一定想得出来,可能需要递归的思想才能写出递推/递归式,有了递推/递归式,之后就可以用递推/递归来设计程序了。
3.递推一般采用开数组(一维或者二维)的方法,递归采用:函数形式的功能单元。
4.另外,有些递归数可以单纯地从数字角度出发找规律得到关系式,也可以用递归的思想去找。