有1000瓶水,其中有一瓶有毒,小白鼠只要尝一点带毒的水24小时后就会死亡,至少要多少只小白鼠才能在24小时时鉴别出那瓶水有毒?

B代表药水,M代表老鼠;Mn代表老鼠正常,Mn'代表老鼠死亡;Bn代表药水正常,Bn'代表药水有毒;


1. 最显而易见的答案是:1000只,每只对应一瓶药水,M1 => B1 , M1' => B1'……。但我们相信还会有更好的答案。



2. 既然每只小白鼠喝一瓶不是最好答案,那就应该每只小白鼠喝多瓶。那每只应该喝多少瓶呢?这是一个很好的思路。我们考虑喝两瓶的情况:


此时老鼠的生死有四种情况:

1. M1M2 => B1B2B3;

2. M1'M2 => B1'B2B3;

3. M1M2' => B1B2B3';

4. M1'M2' => B1B2'B3;

与此类推,1000 : x = 3 : 2 (x向上取整)。

3.但如果我们会想到一只老鼠同时喝两瓶,喝三瓶是否会减少老鼠的数量呢?

此时老鼠的生死有2^3 = 8 种情况,其中两种剔除:

1. M1M2M3 => B1B2B3B4B5;

2. M1'M2M3 => B1'B2B3B4B5;

3. M1'M2'M3 => B1B2'B3B4B5;

4. M1'M2'M3' => B1B2B3'B4B5;

5. M1M2'M3' => B1B2B3B4'B5;

6. M1M2M3' => B1B2B3B4B5';

此时需要老鼠的数量: 1000 : x = 5 : 3 (x向上取整)。这里的x会比第二步的少;

4. 如果增加老鼠同时喝药水的瓶数能够减少实验老鼠所需的数量,那么我们是否可以沿着增加老鼠同时喝药水的瓶数继续往下走?我们先看下四瓶的情况:

通过观察发现:M1'M2'M3' => B1B2B3'B4B5B6 ; M1'M2'M3' => B1B2B3B4'B5B6,同样的结果,我们判断不出到底是B3' 还是B4’;仔细观察我们可以得出这样的规律:
B3和B4引出同样的线并且到达M这边的终点是一致的,也就是只要不存在从B端引出的线的数量和到达B端终点一致的,那么结果就是可以唯一判断的。是否我们可以用数学符号或者表达式来描述这样的规律,也许我们可以很简洁地解决这个问题。这是一个很好的思路。但今天在这里戛然而止,因为我们要跳出思维,从别的方向入手。

5. N只老鼠的生死有2^N种状态,2^10 =  1024 > 1000 ,所以是否10只老鼠就可以了?

因为每只老鼠有生死2中状态,利用2进制,10只老鼠可以有2^10=1024中状态,可

以判断出1000瓶水中有毒的那瓶。将问题域缩小来分析,例如:有7瓶水,其中1瓶有毒,小白鼠只要尝一点带毒

的水24小时后就会死亡,由上可知2^3=8 > 7所以3只就够了.

下面将7瓶水以2进制编号:

001 第一瓶,010 第二瓶,011 第三瓶,100 第四瓶,101 第五瓶,110 第六瓶,111 第七瓶

将3位2进制数第一位为1的瓶子中取出1滴放在一起分给老鼠A,即4,5,6,7瓶

将3位2进制数第二位为1的瓶子中取出1滴放在一起分给老鼠B,即2,3,6,7瓶

将3位2进制数最后三位二进制为1的瓶子中取出1滴放在一起分给老鼠C,即1,3,5,7瓶

然后等24小时,按ABC顺序给死了的老鼠标号为1,没死的为0这个2进制的十进制数就是有毒的瓶子标号

例如第三瓶有毒:则BC老鼠会死,为011=3

第一次看到这个方法感觉很神奇...在网上找了下,这种思想有个算法叫Bloom Filter算法.

猜你喜欢

转载自blog.csdn.net/weixin_39393610/article/details/80179714