Here is the question:
为了得到两个棋子的最优策略,我们先简化问题,看看一个棋子的情况。如果手中只有一个棋子,为了得知临界层面,你只有一种选择:从2楼开始,一层一层地试,直到棋子被打碎,此时你站的楼层就是所求的临界层面。在最差的情况下,我们需要投掷99-2+1=98次,你可能奇怪为什么不是100-2+1=99次,那是因为题目已经告诉我们“从这个大厦的某一层扔下围棋子就会碎”,所以在99层扔下来还没碎的话就不用去100层了——从那里扔它一定会碎。
从一个棋子的策略我们可以看出,一个棋子就足以解答这个问题了。现在又多了一个棋子,该如何利用它呢?很自然地,我们希望能通过这个棋子缩小这种一层一层查找的范围。为了缩小范围,我们将整个大厦的层数分成x段,在这x段中查找那个临界段,然后在临界段中再一层一层地找临界层。比如可以将大楼分成4段,我们分别在25层、50层、75层投掷棋子,以确定临界段;如果临界段在25层到50层,我们再从26层开始一层一层查找临界层。
分析到这里,问题就转化成了如何确定分段数x使棋子投掷的次数最少的问题。在最差的情况下,要确定临界段,我们需要投掷100/x-1次;确定了临界段之后要确定临界层,我们需要再投掷x-1次。因此,问题就成了求函数f(x)=(100/x-1)+(x-1)的最小值问题。先对f(x)求导,f’(x)=1-100/x2,令f’(x)=0求出驻点x=10(x=-10舍去)。由于f(x)存在最小值且只有一个驻点,所以当x=10时f(x)取得最小值,最小值为18。这样就解答了这个问题。
上文贴出之后,我又在CSDN和ChinaUnix的论坛看了一些网友的解法,发现上述方法并非最优。将大楼分段以缩小查找范围的想法是没错的,问题在于是否应该均匀分段。
题目要求我们总的投掷次数要最少。在分段之后,总的投掷次数就等于确定临近段的次数加上确定临界层的次数。如果我们均匀分段,则确定临界层的最坏投掷数是固定的(9次),随着我们确定临近段的投掷次数增加,总的投掷次数也在增加。这样一来,随着临界段的不同,投掷次数也不同。
这也就是为什么上述方法不是最优的原因:投掷次数分布不均。按最坏情况估计,这种方法就多做了几次。为了使最坏情况的投掷数最小,我们希望无论临界段在哪里,总的投掷数都不变,也就是说将投掷数均匀分布。
接下来的解决方案就很容易想出了:既然第一步(确定临界段)的投掷数增加不可避免,我们就让第二步(确定临界层)的投掷数随着第一步的次数增加而减少。第一步的投掷数是一次一次增加的,那就让第二步的投掷数一次一次减少。假设第一次投掷的层数是f,转化成数学模型,就是要求f+(f-1)+...+2+1>=99,即f(f+1)/2>=99,解出结果等于14。
这种方法要推广到n(n>2)个棋子的情况比较困难。我初步的想法是,先用均匀分段求出一个解,然后修正这个解使投掷次数均匀分布。如果你对此有兴趣,不妨思考一下具体的解法。
The key here is to obtain even distribution on how many times in the worst case we have to try regardless where the breaking floor is.
Let's look at the way how we get there, we start with the sequence
(1) 1, 2, 3, 4, 5, 6, 7, 8, 9, ... , 100
Then we take the sum on all numbers before,
(2) 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, ...
The last number 105 > 100, and it's the 14th element in the array (2). Now if we start from the 14th element, which is 14, from the first series (1), if the glass ball breaks, then we need to try at most 13 times below 14th floor to find the breaking floor(start from 1 to 13).
If it's not broken at 14th, then we move up 13 floors(13 is the number before 14) to 27th and check there. If it breaks at 27th, then we know the breaking floor is between 14 and 27(exclude both ends). Since there are only 12 floors in between, totally it takes us 12 + 2 (1 for 14, 1 for 27) trials.
Eventually we will cover all 100 floors(in fact we can cover 105) because 100 < 105 = sum of 1 to 14. And for the first 14 floors, the next 13 floors, the next 12 floors, we all get 14 trials in the worst case.
The floors that we should go if previous trials won't break the glass ball are:
(A) 14, 14+13=27, 14+13+12=39, 14+13+12+11=50, ...
So the process is:
1. take the summations on series (1) to form a new series (2)
2. find the index 14 so that the element with this index, namely 105, is larger than 100.
3. use this index on the series (1) again to sum up backward, namely, series (A).
Once we understand this logic, actually it's easy to extend this method to n glass balls, namely, we just keep taking summations, use (2) as the base and take the summation, we now get
(3) 1, 4, 10, 20, 35, 56, 84, 120, ...
(4) 1, 5, 15, 35, 70, 105, ...
(5) 1, 6, 21, 66, 136, ....
(6) 1, 7, 28, 94, 230, ...
(7) 1, 8, 36, 130,
(8) 1, 9, 45, 175, ...
.............
In every time, we take a evenly distributed series and sum it up to form a new series, then start backward and sum up the new series.
For example, if there are 3 balls, then we use (1), (2), and (3). From (3), 120(The first element > 100) has index 8(from 1, without loss of generality(WLOG)), Then from the 8th element in (2), which 36, we start backward sum-up using (2):
(B) 36, 64, 85, 100, ...
We stop the process once it reaches 100(i.e., >=100, this is because we want to cover 1-100). This series is where we should go, i.e., first try 36, if it's not broken, try 64. If it breaks at floor 36, then it becomes now the case where we have 2 balls and 36 floors. From (2), 36 is the 8th element, this means that we need to start from the 8th element in (1) and sum up backward, ....
If it breaks at 64 and not at 36, then it becomes now the case where we have 2 balls and 64-36=28 balls, if we exclude both ends 64 and 36(since we just tested), we end up 26 balls. Now use the upper bound 28 in 2, we can find the index for (1) and repeat the above.
It's a tedious process, so a program would do the trick for us. The code is largely easy to understand, but there are several cases that twists the logic a little bit:
(i). say floor 5 is broken and there is only one ball, so we have to try from floor 1 to 4, and they are just fine. So logically we know floor 5 is the answer. But the code would print out
something like (5, broken), (4, ok), ...(1, ok).
(ii) say the top floor 5 is the one we are looking for, with only one ball. We have to start from floor 1 on to floor 4. There is no reason to try 5 since it's the top one and every floor below it is ok, so the code has to insert the logic conclusion somewhere.
Noting that though series (1) is evenly distributed(with space 1), it's not the only choice, others are odd number and even numbers(with space 2). However, it's simple to show that when we optimize along space 0, 1, 2, ..., space=1 is the optimal solution(space 0, i.e., the above chinese solution with 10 divided, gives 18; and space 2, i.e., even/odd numbers, give 19).
分享到:
相关推荐
《Redis桌面管理器Another-Redis-Desktop-Manager详解》 Redis,全称为Remote Dictionary Server,是一种高性能的键值存储系统,常被用作数据库、缓存和消息中间件。其简洁的数据结构和丰富的数据类型使其在分布式...
《Redis桌面视图工具Another-Redis-Desktop-Manager在Windows环境下的应用详解》 Redis,全称Remote Dictionary Server,是一款开源、高性能的键值存储系统,常被用作数据库、缓存和消息中间件。其丰富的数据结构和...
标题中的“Another-Redis-Desktop-Manager.1.5.6”指的是Another Redis Desktop Manager的1.5.6版本。这是一款专为Redis数据库设计的桌面管理工具,它提供了直观的图形用户界面(GUI),方便用户进行数据的查看、...
标题 "Another-Redis-Desktop-Manager.1.5.5" 指向的是一款名为 Another Redis Desktop Manager 的软件,其版本号为 1.5.5。这是一款图形用户界面(GUI)工具,专为管理和操作 Redis 数据库而设计。Redis 是一个开源...
1. **界面设计与操作**:该软件的界面设计简洁明了,具有清晰的数据浏览窗口和操作面板,支持多窗口同时管理多个Redis实例。用户可以通过图形化的方式进行键值对的添加、删除、修改以及查看,极大地提高了工作效率。...
《Redis桌面管理器——Another-Redis-Desktop-Manager 1.3.9详解》 Redis,作为一款高性能的键值数据库,广泛应用于缓存、消息队列等多种场景。为了更好地管理和操作Redis数据库,开发者们设计了一系列的桌面管理...
**Redis桌面管理工具Another-Redis-Desktop-Manager 1.3.7版详解** Redis,全称为Remote Dictionary Server,是一款高性能的键值存储系统,常用于数据库、缓存和消息中间件等场景。其轻量级、速度快的特性使得它在...
Redis桌面(GUI)管理客户端
Redis桌面(GUI)管理客户端
免费神器,redis可视化客户端,支持5.0 stream数据结构
Redis桌面(GUI)管理客户端
Redis桌面(GUI)管理客户端
Another Redis Desktop Manager(简称ARDM)是一个开源的Redis桌面管理工具,它提供了一个图形用户界面(GUI)来方便用户对Redis数据库进行管理和操作。以下是对ARDM 1.6.6版本的简单介绍: 版本:1.6.6 发布日期:...
"Another-Redis-Desktop-Manager.1.4.8"就是这样一个适用于Windows的Redis桌面管理工具。 该工具提供了图形化的界面,使得Redis的日常管理和维护变得更加简单。它支持多种功能,包括连接到本地或远程的Redis服务器...
标题中的"Another-Redis-Desktop-Manager.1.3.8.rar"指的是一个名为"Another Redis Desktop Manager"的软件的版本1.3.8的压缩文件。这是一款针对Redis数据库的桌面管理工具,用于帮助用户在Windows操作系统上更加...
《Another Redis Desktop Manager 1.6.1:免费的Redis可视化管理工具》 Redis,一个高性能的键值数据库,广泛应用于缓存、消息队列、数据存储等多个领域。为了更方便地管理和操作Redis数据库,出现了许多桌面管理...
Redis可视化界面
Redis桌面(GUI)管理客户端
Another-Redis-Desktop-Manager.1.4.2
"Another-Redis-Desktop-Manager.1.5.5.7z" 是一个针对Redis的桌面图形用户界面(GUI)管理工具的压缩包,版本为1.5.5。 Redis Desktop Manager是一款跨平台的Redis管理软件,它提供了一个直观且功能丰富的界面,...