源本科技 | 码上会

兔子繁殖问题

2026/01/26
40
0

题目

有一对兔子,从出生后第 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 个月的兔子总对数:

月份 n

兔子对数 f(n)

说明

1

1

初始一对幼兔

2

1

还未成熟,不能生育

3

2

原来的一对成熟并生出一对

4

3

原来的继续生,新出生的还未成熟

5

5

第 3 个月出生的现在成熟了,也开始生

6

8

又多了一对可生育的兔子

可以看出:

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