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。

京公网安备 11010502036488号