0
点赞
收藏
分享

微信扫一扫

#yyds干货盘点# 解决华为机试: 统计每个月兔子的总数

1.简述:

描述

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

本题有多组数据。

数据范围:每组输入满足 1 \le n \le 31 \1≤n≤31 

输入描述:

多行输入,一行输入一个int型整数表示第n个月

输出描述:

每一行输出对应的兔子总数

示例1

输入:

1
2
3
4
5
9

复制输出:

1
1
2
3
5
34

2.代码实现:

方法一:递推

解题思路:

利用动态规划的思想,通过规律进行递推,找出

算法流程:

分别用三个变量表示:一、二、三月龄兔子数量,addVal 保存下个月将繁殖的兔子数量

第二个月开始递推:

三月龄及以上兔子总数 = 二月龄兔子总数 + 原本三月龄及以上兔子总数

二月龄兔子总数 = 上个月的一月龄兔子总数

一月龄(即这个月出生)兔子总数 = 上个月将繁殖的兔子数量、

下个月将出生的兔子 = 下个月成为三月龄及以上的兔子数量

最后返回第 N 个月的总量即可

import java.util.*;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
System.out.println(solution(scanner.nextInt()));
}

}

private static int solution(int month) {
// 第一个月初始化
// 一月龄兔子总数
int oneMonth = 1;
// 二月龄兔子总数
int twoMonth = 0;
// 三月龄及以上兔子总数
int threeMonth = 0;
// 下个月将繁殖的兔子数量
int addVal = 0;
// 第二个月开始递推, i表示第i个月
for(int i = 2; i <= month; i++) {
// 三月龄及以上兔子总数 = 二月龄兔子总数 + 原本三月龄及以上兔子总数
threeMonth += twoMonth;
// 二月龄兔子总数 = 上个月的一月龄兔子总数
twoMonth = oneMonth;
// 一月龄(即这个月出生)兔子总数 = 上个月将繁殖的兔子数量
oneMonth = addVal;
// 下个月将出生的兔子 = 下个月成为三月龄及以上的兔子数量
addVal = twoMonth + threeMonth;
}
return (oneMonth + twoMonth + threeMonth);
}
}

方法二:递归

解题思路:

递归中可以通过备忘录减少重叠子问题

算法流程:

维护一个备忘录,用来保存计算过的状态,减少重叠子问题

明确定义递归函数:返回第n个月兔子总量

递归终止条件:n == 1 或 n == 2时,即第一和第二个月的兔子总数为1

如果备忘录已经保存了该月份的数据,表示已经计算过,直接返回即可,不需要再计算

根据规律以及函数定义,进行递归调用,同时保存状态到备忘录

import java.util.*;

public class Main {
// 备忘录,减少重叠子问题
private static int[] memo;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int month = scanner.nextInt();
// 备忘录里的元素都初始化为-1
memo = new int[month + 1];
Arrays.fill(memo, -1);
System.out.println(dp(month));
}

}

// 返回第n个月兔子总量
private static int dp(int n) {
// 递归终止条件
if(n <= 2) {
return 1;
}
// 使用备忘录
if(memo[n] != -1) {
return memo[n];
}
// 递归调用,满足规律
memo[n] = dp(n - 1) + dp(n - 2);
return memo[n];
}
}
举报

相关推荐

0 条评论