有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
这是一个经典的 斐波那契数列 问题,常被称为“兔子繁殖问题”,最早由意大利数学家 斐波那契 在 1202 年提出。
初始有一对刚出生的兔子。
兔子从 出生后第 3 个月起(即满 2 个月后),每个月生一对新兔子。
所有兔子 永不死。
每对新生兔子也遵循相同规律。
问:第 n 个月共有多少对兔子?
第 1 个月: 1 对兔子
第 2 个月: 1 对兔子
第 3 个月: 2 对兔子
第 4 个月: 3 对兔子
第 5 个月: 5 对兔子
第 6 个月: 8 对兔子
第 7 个月: 13 对兔子
第 8 个月: 21 对兔子
第 9 个月: 34 对兔子
第 10 个月: 55 对兔子
第 11 个月: 89 对兔子
第 12 个月: 144 对兔子我们用 f(n) 表示第 n 个月的兔子总对数:
可以看出:
f(n) = f(n - 1) + f(n - 2)
为什么是这个递推式?
f(n - 1):上个月的所有兔子都活到本月(兔子不死)。
f(n - 2):上上个月的所有兔子在本月都能生育(因为它们已满 2 个月,进入第 3 个月),每对生 1 对 → 新增 f(n - 2) 对。
因此,本月总数 = 上月总数 + 新生数量 = f(n-1) + f(n-2)。
这正是 斐波那契数列 的定义。
初始条件:
f(1) = 1
f(2) = 1
推荐:使用迭代法(高效、O(n) 时间,O(1) 空间)
public class RabbitProblem {
public static void main(String[] args) {
int n = 20;
for (int i = 1; i <= n; i++) {
System.out.println("第 " + i + " 个月: " + fib(i) + " 对兔子");
}
}
// 迭代法计算斐波那契数列第 n 项
public static long fib(int n) {
if (n == 1 || n == 2) {
return 1;
}
long a = 1, b = 1; // f(1), f(2)
long temp;
for (int i = 3; i <= n; i++) {
temp = a + b; // f(i) = f(i-1) + f(i-2)
a = b;
b = temp;
}
return b;
}
}使用
long而非int是为了避免整数溢出(第 47 项就超过int最大值)。
此数列在自然界广泛存在:花瓣数目、松果螺旋、贝壳生长等。
黄金比例 φ ≈ 1.618,相邻两项比值 f(n)/f(n-1) 随 n 增大趋近于 φ。
若需计算第 100 项或更高,建议使用 BigInteger 避免溢出。
兔子问题本质是 斐波那契数列建模。
递推关系:f(n) = f(n-1) + f(n-2),f(1)=f(2)=1。
编程时优先使用 迭代法 提升效率。
注意数据类型选择,防止溢出。
因此,第 n 个月的兔子总对数就是 斐波那契数列的第 n 项。