一个问题的解法(兔子三个月之后每月都生兔子的问题)
今天看到一个问题,其实是老问题了,心血来潮,就解决了一下,问题如下:
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数?
这个问题想了有一个小时才想明白,看来智力水平一般,如果要是去面试这道题,肯定不行,所以还是记下来。
将兔子分为3类,一类是可以生兔子的,一类是出生一个月的,一类是出生两个月的,这样做一个简单图表如下:
月份 | 0 | 1 | 2 | 3 | 4 | 5 |
可以生产的兔子 | 1 | 1 | 1 | 2 | 3 | 4 |
1个月大的兔子 | 0 | 1 | 1 | 1 | 2 | 3 |
2个月大的兔子 | 0 | 0 | 1 | 1 | 1 | 2 |
可以看出如下的等式
某月的可以生育的兔子=上月可以生育的兔子+上月出生2月的兔子
某月的一月的兔子=上月可以生育的兔子
某月的二月的兔子=上月为1月的兔子
即:上月可以生育的兔子产生了等数量的1月的兔子,上月1月的兔子变成了2月的兔子,上月2月的兔子变成可以生育的兔子
所以可以构建一个数组表示:
a[n+1][0]=a[n][0]+a[n][2]
a[n+1][1]=a[n][0]
a[n+2][2]=a[n][1]
其中a[0][0]=1,a[0][1]=0,a[0][2]=0
这很容易用递归函数求出月龄不同的兔子数量,总量只要加起来就可以了,用任何语言实现起来都很容易,下面用Java实现:
package rabbit;
/**
*
* @author flysy
*/
public class rabbitNum {
public static long getRabbitNum(int k, int i) {
if ((k == 0) && (i == 0)) {
return 1;
}
if ((k == 0) && (i == 1)) {
return 0;
}
if ((k == 0) && (i == 2)) {
return 0;
}
if (i == 0) {
return getRabbitNum(k - 1, 0) + getRabbitNum(k - 1, 2);
}
if (i == 1) {
return getRabbitNum(k - 1, 0);
}
if (i == 2) {
return getRabbitNum(k - 1, 1);
}
return 0;
}
public static void main(String[] args) {
System.out.println("i\t3月\t2月\t1月\t总量");
for (int i = 0; i < 100; i++) {
long s0 = getRabbitNum(i, 0);
long s1 = getRabbitNum(i, 1);
long s2 = getRabbitNum(i, 2);
long sum = s0 + s1 + s2;
System.out.println(i + "\t" + s0 + "\t" + s1 + "\t" + s2 + "\t" + sum);
}
}
}
因为兔子增长的很快,所以用long类型取代int型,输出如下
i 3月 2月 1月 总量
0 1 0 0 1
1 1 1 0 2
2 1 1 1 3
3 2 1 1 4
4 3 2 1 6
5 4 3 2 9
6 6 4 3 13
7 9 6 4 19
8 13 9 6 28
9 19 13 9 41
10 28 19 13 60
11 41 28 19 88
12 60 41 28 129
.........................
这种方式的问题是重复递归的太厉害,在我的电脑上输出到45之后,就变得非常慢了。所以需要优化一下,可以保存一下中间变量,避免重复递归,修改的程序如下:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package rabbit;
/**
*
* @author flysy
*/
public class RabbitNum1 {
static long a[][] = new long[1000][3];
public static long getRabbitNum(int k, int i) {
if (k == 0) {
return a[k][i];
} else {
for (int m = 0; m < 3; m++) {
if (a[k - 1][m] == 0) {
a[k - 1][m] = getRabbitNum(k - 1, m);
}
}
if (i == 0) {
return a[k - 1][0] + a[k - 1][2];
}
if (i == 1) {
return a[k - 1][0];
}
if (i == 2) {
return a[k - 1][1];
}
return 0;
}
}
public static void main(String[] args) {
a[0][0]=1;
System.out.println("i\t3月\t2月\t1月\t总量");
for (int i = 0; i < 100; i++) {
long s0 = getRabbitNum(i, 0);
long s1 = getRabbitNum(i, 1);
long s2 = getRabbitNum(i, 2);
long sum = s0 + s1 + s2;
System.out.println(i + "\t" + s0 + "\t" + s1 + "\t" + s2 + "\t" + sum);
}
}
}
结果是瞬间就出来了,如下:
i 3月 2月 1月 总量
0 1 0 0 1
1 1 1 0 2
2 1 1 1 3
3 2 1 1 4
4 3 2 1 6
5 4 3 2 9
6 6 4 3 13
7 9 6 4 19
8 13 9 6 28
9 19 13 9 41
10 28 19 13 60
11 41 28 19 88
12 60 41 28 129
13 88 60 41 189
14 129 88 60 277
15 189 129 88 406
16 277 189 129 595
17 406 277 189 872
18 595 406 277 1278
19 872 595 406 1873
20 1278 872 595 2745
21 1873 1278 872 4023
22 2745 1873 1278 5896
23 4023 2745 1873 8641
24 5896 4023 2745 12664
25 8641 5896 4023 18560
26 12664 8641 5896 27201
27 18560 12664 8641 39865
28 27201 18560 12664 58425
29 39865 27201 18560 85626
30 58425 39865 27201 125491
31 85626 58425 39865 183916
32 125491 85626 58425 269542
33 183916 125491 85626 395033
34 269542 183916 125491 578949
35 395033 269542 183916 848491
36 578949 395033 269542 1243524
37 848491 578949 395033 1822473
38 1243524 848491 578949 2670964
39 1822473 1243524 848491 3914488
40 2670964 1822473 1243524 5736961
41 3914488 2670964 1822473 8407925
42 5736961 3914488 2670964 12322413
43 8407925 5736961 3914488 18059374
44 12322413 8407925 5736961 26467299
45 18059374 12322413 8407925 38789712
46 26467299 18059374 12322413 56849086
47 38789712 26467299 18059374 83316385
48 56849086 38789712 26467299 122106097
49 83316385 56849086 38789712 178955183
50 122106097 83316385 56849086 262271568
51 178955183 122106097 83316385 384377665
52 262271568 178955183 122106097 563332848
53 384377665 262271568 178955183 825604416
54 563332848 384377665 262271568 1209982081
55 825604416 563332848 384377665 1773314929
56 1209982081 825604416 563332848 2598919345
57 1773314929 1209982081 825604416 3808901426
58 2598919345 1773314929 1209982081 5582216355
59 3808901426 2598919345 1773314929 8181135700
60 5582216355 3808901426 2598919345 11990037126
61 8181135700 5582216355 3808901426 17572253481
62 11990037126 8181135700 5582216355 25753389181
63 17572253481 11990037126 8181135700 37743426307
64 25753389181 17572253481 11990037126 55315679788
65 37743426307 25753389181 17572253481 81069068969
66 55315679788 37743426307 25753389181 118812495276
67 81069068969 55315679788 37743426307 174128175064
68 118812495276 81069068969 55315679788 255197244033
69 174128175064 118812495276 81069068969 374009739309
70 255197244033 174128175064 118812495276 548137914373
71 374009739309 255197244033 174128175064 803335158406
72 548137914373 374009739309 255197244033 1177344897715
73 803335158406 548137914373 374009739309 1725482812088
74 1177344897715 803335158406 548137914373 2528817970494
75 1725482812088 1177344897715 803335158406 3706162868209
76 2528817970494 1725482812088 1177344897715 5431645680297
77 3706162868209 2528817970494 1725482812088 7960463650791
78 5431645680297 3706162868209 2528817970494 11666626519000
79 7960463650791 5431645680297 3706162868209 17098272199297
80 11666626519000 7960463650791 5431645680297 25058735850088
81 17098272199297 11666626519000 7960463650791 36725362369088
82 25058735850088 17098272199297 11666626519000 53823634568385
83 36725362369088 25058735850088 17098272199297 78882370418473
84 53823634568385 36725362369088 25058735850088 115607732787561
85 78882370418473 53823634568385 36725362369088 169431367355946
86 115607732787561 78882370418473 53823634568385 248313737774419
87 169431367355946 115607732787561 78882370418473 363921470561980
88 248313737774419 169431367355946 115607732787561 533352837917926
89 363921470561980 248313737774419 169431367355946 781666575692345
90 533352837917926 363921470561980 248313737774419 1145588046254325
91 781666575692345 533352837917926 363921470561980 1678940884172251
92 1145588046254325 781666575692345 533352837917926 2460607459864596
93 1678940884172251 1145588046254325 781666575692345 3606195506118921
94 2460607459864596 1678940884172251 1145588046254325 5285136390291172
95 3606195506118921 2460607459864596 1678940884172251 7745743850155768
96 5285136390291172 3606195506118921 2460607459864596 11351939356274689
97 7745743850155768 5285136390291172 3606195506118921 16637075746565861
98 11351939356274689 7745743850155768 5285136390291172 24382819596721629
99 16637075746565861 11351939356274689 7745743850155768 35734758952996318