用js编写:一堆香蕉,来了三只猴子,第一只猴子把这堆香蕉分成三堆,

JavaScript022

用js编写:一堆香蕉,来了三只猴子,第一只猴子把这堆香蕉分成三堆,,第1张

一堆香蕉,来了三只猴子,第一只猴子把这堆香蕉分成三堆,正好剩一个,于是它拿走一堆和一个。第二个猴子来的时候做同样的操作,最后一个猴子也相同。三只猴子走后,来了五只猴子,这回分五堆剩一个,它拿走一堆加一个。问最开始那堆香蕉最少有多少个?

最后一次分香蕉,即五只猴子分为五堆,此时,每堆香蕉至少有一个,其中一只猴子拿走一堆加一个,就是两个。现在每堆香蕉最少一个,依次往前推,可推出最开始那堆香蕉最少个数。如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

package play

public class Test {

public static void main(String[] args) {

getMinCount(1)

}

/**

*

* @param min最后一次分堆,每一堆最少香蕉个数

*/

private static void getMinCount(long min) {

// 最后一次分香蕉

long startMin = 5 * min + 1

int count = 3

while (count >0) {

count--

startMin = 3 * startMin + 1

}

System.out.println(startMin)

}

}

假设猴子往前走x米,把一部分香蕉转移到x米处,留x个香蕉路上吃,然后折返,重复如此,把所有香蕉先搬到x米处,显然每次搬运会浪费2x个香蕉,最后一次浪费x个,由此易知搬运的次数越少越好,我们定为2次,那么每次浪费3x个香蕉,还剩100-3x个香蕉,还需要走50-x米,显然剩下的路一次走完要更优,那么最后留下的香蕉数是 min(100-3x,50)-(50-x) 求个最大值 易知为x=17时 原式求值为16

其次:解法

前面每前进1米,就要3趟,也就是吃掉3个香蕉;当然不可能50米全部这样,因为没有150个香蕉够吃^_^

这就需要找到一个点,当小猴子拿香蕉时能拿最多的香蕉(<=50),这样它可以一次到家,不用再往返。

设Y为要求的香蕉最大剩余数,X为要求的那个点(X米),可以列出方程式:

1. Y=(100-3X) - (50-X)

2. (100-3X)<=50

很容易求出Y=16

另外看到这样一种解法:

倘若可以先吃再走,可以剩下18根

(方法)背第1桶50根的香蕉到离出发点16又1/3公尺处(A点),留下一根香蕉

回去搬第2桶50根的香蕉,在回到离出发点16又1/3公尺处(A点)

这时总共走了16又1/3×3=49公尺,吃掉49根

此时吃下A点的那一根,背起第2桶50根的香蕉,可以多走1公尺,到离出发点17又1/3公尺处(B点),此时距离终点还有50-17又1/3=32又2/3公尺

32又2/3公尺只需32根, 剩下2/3公尺不足1公尺,可以不吃

故最后剩下50-32=18根