问题
生物学家小 R 正在研究一种特殊的兔子品种的繁殖模式。这种兔子的繁殖遵循以下规律:
- 每对成年兔子每个月会生育一对新的小兔子(一雌一雄)。
- 新生的小兔子需要一个月成长,到第二个月才能开始繁殖。
- 兔子永远不会死亡。
小 R 从一对新生的小兔子开始观察。他想知道在第 A 个月末,总共会有多少对兔子。
请你帮助小 R 编写一个程序,计算在给定的月份 A 时,兔子群体的总对数。
注意
- 初始时有 1 对新生小兔子。
- 第 1 个月末有 1 对兔子:原来那对变成了成年兔子,并开始繁殖。
- 第 2 个月末有 2 对兔子:原来那 1 对成年兔子,繁殖了 1 对新生的小兔子。
- 从第 3 个月开始,兔子群体会按照上述规律增长。
解释与作答
从我们学过的递归角度来讲,这类问题的实现算是举手之劳。 第一个月 有一对小的,我们称之为a 第二个月 a成长为A 又生了一个a 为 Aa 第三个月 AAa 第四个月 AAAaa 第五个月 AAAAAaaa 以此类推。。。 第n个月 A=n-1个月的兔子总数 a=n-1个月的A 也就是n-2个月的兔子总数 所以可以写出基础的递归代码:
def solution(A: int) -> int:
if A == 1:
return 1
if A == 2:
return 2
return solution(A - 1) + solution(A - 2)
但是这种写法还是太过重复了。 因为在过程的计算中,一些已经算出来的数没有被记住,从而又被算了一遍 如果是很大的数字,那么重复的次数就会无限的增多。 那么好,我们要解决这个问题,就只需要把计算出来的月份的数值记录下来就可以了。
def fibonacci_rabbits(A):
# 如果月份小于等于1,兔子对数为1
if A <= 1:
return 1
# 初始化数组,存储每个月的兔子对数
rabbits = [0] * (A + 1)
# 第一个月和第二个月的兔子对数都是1
rabbits[1] = 1
rabbits[2] = 1
# 从第三个月开始计算兔子对数
for i in range(3, A + 1):
rabbits[i] = rabbits[i - 1] + rabbits[i - 2]
# 返回第A个月末的兔子对数
return rabbits[A]
# 示例:计算第5个月末的兔子对数
A = 5
print(f"在第{A}个月末,总共会有{fibonacci_rabbits(A)}对兔子。")
这就很nice。 算法的时间复杂度为O(A); 减少了不止一点。