1、有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?

2、本题有多组数据。

方法一:归纳总结

所有兔子就三种,每个月更新三种的数量:

迭代完全部相加即为所有兔子数量count;

第三个月及以上,可生育big;

第二个月,不可生育little;

第一个月,小萌新little。

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int n = in.nextInt();//输入数据
            int count = 0;
            int rabbitLittle = 1;//一月新生兔子
            int rabbitBig = 0;//二月大或者更多月份的兔子
            for (int j = 0; j < n; j++) {
                count = rabbitLittle + rabbitBig;//本月兔子数量=一月新生兔子+二月大兔子
                rabbitLittle = rabbitBig;//下个月,每个二月大兔子将会生产 一个 一月新生兔。
                rabbitBig = count; //下个月所有二月大兔子将会满足 两个月大兔子的 条件。
            }
            System.out.println(count);
        }
    }

方法二:斐波那契数列

具体方法

我们可以先来推导一个

第一个月 只有一对

第二个月 只有一对

第三个月 原先的一对生出一对 共2对

第四个月 最开始的一对又生出一对 共3对

第五个月 第一对生一对,第二队到第三月 生一对,共5对

第六个月 第一对生一对,第二对生一对,第三对生一对,共8对

可以发现f(n) = f(n-1)+f(n-2)

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            int n = sc.nextInt();
            System.out.println(f(n));
        }
    }
    public static int f(int n){
        if(n == 1 || n == 2){
            return 1;
        }
        return  f(n-1)+f(n-2);
    }
}


复杂度分析:

  • 时间复杂度:O(2n)O(2^n)O(2n),如图所示,树型递归,遍历每个结点
  • 空间复杂度:O(n)O(n)O(n),递归栈最大深度为n

方法三:动态规划

具体做法

设第n个月的兔子数量为num[n],第n个月有第n-1个月已有的兔子,同时,可能会有新出生的兔子。由题目可知,每只兔子在第三个月都会生一只兔子,所以第n个月出生的兔子数量等于第n-2月时的兔子数量,即num[n]=num[n-1]+num[n-2]。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            int n = sc.nextInt();
            System.out.println(dp(n));
        }
    }
    public static int dp(int n){
        int num[] = new int[n+1];
        num[1] = 1;
        num[2] = 1;
        for(int i=3;i<=n;i++){
            num[i] = num[i-1] + num[i-2];
        }
        return  num[n];
    }
}


复杂度分析

  • 时间复杂度:O(n)O(n)O(n),动态规划需要遍历一遍。
  • 空间复杂度:O(n)O(n)O(n),动态规划数组大小为n。