关于“古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子……” 理清问题,无往而不胜

被一窝兔子绊倒!

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

本人是在搜问题时,发现有伙伴在百度提问,并试着理解并寻找问题发生的根源 —— 误解了题目,还是解题困难。通过接受和理解问题提出者的困惑后,发现疑惑和误解是可以理解的,我试着为题目增加一些限制和说明,使得对题目的把握更加准确,或者说减少题目本身存在的歧义,使之更加明确。至于问题的解法,方法有多种,而且提供解法的文章数不胜数,不再赘述,如需了解,请再简单搜索一下。

(百度问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子.如果您看到这两处的说法一样,不要奇怪,都出自于本人。其中内容包括问题的直接回答,及对其中一个回答者的内容进行评论,即回答了其中一个回答者的回复

题干分析(减少歧义)不可将 “第3个月”看成了(理解成)“隔3个月”。准确的理解是“如 当下是1月初,2月初则是第二月,3月初就是第三个月”。这里如果说成两月即61天(2个月,忽略闰二月,假如闰二月时,按月算)后。这样会减少不是歧义。

问题解析:这是一个典型的“波非那切数列”:前面相邻两项之和,构成了后一项(即:后一项,总等于前两项之和)。

关于:“前面相邻两项之和,构成了后一项”的理解:(
依据:“第3个月起每个月都生一对”(这里容易造成误解的是,第3个月起,这个起始时间点,是指月初还是月末的问题,从这个经典问题的初衷来说,是指的月初)。
因此:“第3个月,即隔2个月(约61天,闰月则忽略并按月来算)就发生”。
结论:
(1) 上一个月的兔子(n),在下一个月,保持到下一月(n);即 老兔数 = 上月兔子总数。
(2) 第3月出生的兔仔,由上上月(第 前3月)的兔子所生,且是1对 生 1对,1:1的比例。及 兔仔数 = 上上月的兔子总数。
(3) 总数 = 上月兔子总数 + 上上月的兔子总数(也即 相邻两项之和)

个人的一段小解法:

(1)迭代算法方式

 1 package com.activitiserver;
 2 
 3 public class server {
 4 
 5     // 1   1    2   3   5
 6     public static void main(String[] args) {
 7         int month;
 8         for (int i = 1;i<10;i++){
 9             month = i;
10             int count = printCountByMonth(month);
11             System.out.println("第" + month + "月,小兔数为:" + count +"(对)");
12             System.out.println();
13         }
14     }
15 
16     public static int printCountByMonth(int month){
17         if (month < 1) throw new RuntimeException("月数不可小于1个月");
18         int first = 1;
19         int second = 1;
20         int third = 0;
21         if (month == 1 || month == 2) return 1;
22         boolean flag = true;
23         while (month > 0){
24             first = second;
25             second = third;
26             third = first + second;
27             month --;
28             if (flag){
29                 flag = false;
30             }else{
31                 System.out.print(",");
32             }
33             System.out.print(third);
34         }
35         System.out.println();
36         return third;
37     }
38 }

运行结果: 

第1月,小兔数为:1(对)

第2月,小兔数为:1(对)

1,1,2
第3月,小兔数为:2(对)

1,1,2,3
第4月,小兔数为:3(对)

1,1,2,3,5
第5月,小兔数为:5(对)

1,1,2,3,5,8
第6月,小兔数为:8(对)

1,1,2,3,5,8,13
第7月,小兔数为:13(对)

1,1,2,3,5,8,13,21
第8月,小兔数为:21(对)

1,1,2,3,5,8,13,21,34
第9月,小兔数为:34(对)


Process finished with exit code 0

 (2)递归算法方式

 1 public class BFNQFun {
 2     public static void main(String[] args) {
 3         int in = 9;
 4         int count = getCount(in);
 5         System.out.println();
 6         System.out.println("in = " + in+ ",getCount = " + count);
 7     }
 8 
 9     public static int getCount(int in){
10         System.out.print(in + ",");
11         if (in <= 0) return 1;
12         if (in == 1) return 1;
13         return getCount(in - 1) + getCount(in - 2);
14     }
15 }

运行结果:(为了便于阅读,对下面的换行是手动修改的,并非原样,但数据总数不变)  

9,8,7,6,5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,4,3,2,1,0,1,2,1,0,
5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,6,5,4,3,2,1,0,1,2,1,0,3,2,
1,0,1,4,3,2,1,0,1,2,1,0,7,6,5,4,3,2,1,0,1,2,1,0,3,2,1,0,
1,4,3,2,1,0,1,2,1,0,5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,

in = 9,getCount = 55

小结:

从打印的“,”符号统计:

迭代算法:35个“,”  .

递归算法:108个“,” .

即可得出:效率 递归算法 弱与 迭代算法,也就是说,本次运算中 递归算法 优于 迭代算法。

原文地址:https://www.cnblogs.com/bridgestone29-08/p/13228994.html