一,常规的问题
问题背景:
1000瓶药水,有一瓶有毒,小老鼠喝下去之后会在1小时死亡。问给你一小时你需要多少只老鼠才能检测出那瓶是毒药?
分析问题:
最优的方法是进制法去求解。因为时间是一个小时在喝下药水之后小老鼠的状态有生和死两种状态,对应着二进制中的0和1,因此可以用二进制的想法去求解。因为
2^10=1024
所以需要10只老鼠就可以检测出毒药。先给出解法步骤:
解法:1,将1000瓶药水按照二进制进行标记;
2,定义10个符号位,从左至右分别为符号位1....10,每个符号位为0或者1。10只老鼠按照从左到右的位置,代表每一个符号位的位置;
3,对于每个老鼠按照如下操作:喝其相应位置中序列为1的药水,如果一个小时候老鼠死了,那么该序列为1,如果没死,则该序列为0.
4,最后得到每个序列对应的数字就是有毒的那瓶药水的二进制编码。
懵逼吧。举个栗子就好理解了。问题简化成4瓶药水,两只老鼠,来看看。
两只老鼠A,B;4瓶药水00,01,10,11
答案:_ _
目标是求出答案中两个符号位的数字。假设现在有毒的是10;
A表示左一位置的状态,B表示左二位置的状态。
A喝第一位置中序列为1的药水,就是10,11,结果死了(因为10有毒),那么左一的符号位是1;
B喝第二位置中序列为1的药水,就是01,11,结果没死,那么左二的符号位是0;
最后得到有毒的是标记为10的那瓶,跟我们设置的一样。
还不明白的可以调换一下有毒的瓶子,再自己推演一下就能明白了。
二,一个问题
明白的继续往下看,想一个问题:为什么死的时候置为1,生的时候置为0 ?
这个问题很关键,如果明白了这个问题,下面的扩展就很容易理解了了。
如果你觉得我把这个问题想明白了,那恐怕你要失望了,我没有完全弄懂。
不过我知道设置为1还是0是跟小老鼠喝药水的序列号是相关的,如果喝的是序列1的那么死为1生为0;如果喝的是序列0的那么死为0生为1.得到的结论就是:喝序列号是多少,那么死就设置成该序列号。
不相信的可以以上面两只老鼠4瓶药水为例,以喝序列号为0,死为0生为1,推演一遍。
三,问题扩展
记住上面的结论:小老鼠喝序列号是多少,那么死就设置成该序列号
继续看问题的扩展:
1000瓶药水,有一瓶有毒,小老鼠喝下去之后会在1小时死亡。假设现在给你两个小时你需要至少需要多少只老鼠能检测出那瓶是毒药?
还是以进制法为基础进行分析:
小老鼠在喝完药水一个小时之后会产生状态,那个两个小时小老鼠会有多少状态?
答案是三种。即,死,生死,生生。
以生死为例,表示小老鼠喝完药水一个小时之后活蹦乱跳的,再继续和药水一个小时之后死了。其他两种情况可以自己推算到。
那么就是说老鼠有三种状态,则可以用三进制的思路去考虑问题了。因为
3^5=243>100
因此理论上5只老鼠就可以算出哪瓶有毒。解法如下:
解法:1,将1000瓶药水按照三进制进行标记;
2,定义5个符号位,从左至右分别为符号位1....5,每个符号位为0,1或者2。5只老鼠按照从左到右的位置,代表每一个符号位的位置;
3,对于每个老鼠按照如下操作:喝其相应位置中序列为0的药水,如果一个小时候老鼠死了,那么该序列为0;如果没死,喝其相应位置中序列为1的药水,如果死了,则该序列为1,如果活着则该位置为2;
(因为一个小时能知道小老鼠的状态,因此两个小时可以喝两次药水)
4,最后得到每个序列对应的数字就是有毒的那瓶药水的三进制编码。
还是懵逼?没关系继续举个栗子就好理解了。问题简化成8瓶药水,两只老鼠,来看看。
两只老鼠A,B;4瓶药水00,01,02,10,11,12,20,21
答案:_ _
目标是求出答案中两个符号位的数字。假设现在有毒的是10;
A表示左一位置的状态,B表示左二位置的状态。
A喝第一位置中序列为0的药水,就是00,01,02,没死;继续和第一位置为1的药水,就是10,11,12,结果死了(因为10有毒),那么左一的符号位是1;
B喝第二位置中序列为0的药水,就是00,10,20,结果死了(因为10有毒),那么左二的符号位是0;
最后得到有毒的是标记为10的那瓶,跟我们设置的一样。
相信你已经看明白了吧。
那么如果再扩展一下,假定给了3个小时,100瓶药水至少需要多少只老鼠呢?
如果你看懂了肯定就知道答案了。
有什么不懂的欢迎下方提问。
网上解释的比较偏原理的连接: