1000瓶药水,1瓶毒药

题目

有1000瓶药水,其中1瓶是毒药,普通药水不会致死,而毒药1滴也会导致一天之后死亡。现有老鼠若干,如何用最少的时间,最少的老鼠,找出毒药?

只追求时间

用1000只老鼠,1只老鼠对应一瓶药水。1天时间即可找出毒药。

优点:只需1天,能以最快的时间找到毒药
缺点:需要1000只老鼠,使用的老鼠太多

只追求空间

使用二分法,第一轮,将药水分为两组,1组500瓶,用1只老鼠,1瓶喝1滴,根据老鼠是否中毒即可排除其中1组。第二轮,将有毒的一组药水重新分为两组,重复上一轮的操作。

第一轮:剩余500瓶
第二轮:剩余250瓶
第三轮:剩余125瓶
第四轮:剩余62瓶/63瓶
第五轮:剩余31瓶/32瓶
第六轮:剩余15瓶/16瓶
第七轮:剩余7瓶/8瓶
第八轮:剩余3瓶/4瓶
第九轮:剩余1瓶/2瓶
第十轮:剩余1瓶

可以发现:
最多经历10轮,也就是10天之后,才能找到毒药。
最多需要10只:每轮老鼠喝的药水都含有毒药
最少需要1只:老鼠在每1轮中都没有喝到毒药

平衡一下

上面两个方法,要么需要的老鼠太多,要么等的时间太久,能不能结合一下呢?

改善方案

第一轮:把药水分成10份,每轮使用9只老鼠。
第一轮:剩余100瓶
第二轮:剩余10瓶
第二轮:剩余1瓶
最多3天,即可找出毒药

规律总结

第一轮:把药水分成a份,每轮使用a-1只老鼠
···
最多需要 l o g a 1000 log_{a}1000 loga1000

从二进制的角度思考

先分析4瓶药水怎么判断

如果有4瓶水,需要几只小白鼠?

首先对这四瓶水进行编号,0,1,2,3,转换为二进制,00,01,10,11。

每一位代表1只小白鼠,显然需要2只小白鼠,

然后根据二进制编号决定哪瓶药水给哪只老鼠喝

00,表示标号为0的水,不给第一只小白鼠喝,也不给第2只小白鼠喝。

01,表示标号为1的水,不给第一只小白鼠喝,但是给第2只小白鼠喝。

10,表示标号为2的水,给第一只小白鼠喝,不给第二只小白鼠喝。

11,表示标号为3的水,既给第一只小白鼠喝,也给第二只小白鼠喝。

注意了,我们给4瓶水分别编号 0 1 2 3,换算成二进制,00 01 10 11,这四个编码有两个方向的含义:

  • 一个是从水到小白鼠的,即某瓶水对应的2位二进制编码,位 i (i = 0 或 1)代表了这瓶水要不要给第 i 只小白鼠喝。

  • 一个是从小白鼠到水的,即两只小白鼠代表两个二进制位,其死(1)活(0)就代表那一位上的值,如果第一只小白鼠死了,那么第一位就是1否则为0,第二只则对应了第二位。

因此我们把四瓶水按照它们对应的编码分别喂给对应的小白鼠,最后小白鼠的状态编码就能标识出这四瓶水中哪一瓶是有毒的。

假如实验结果是两只小白鼠都活着,那么对应的编码就是 00,说明编号为00药水有毒。(编号00,说明两只老鼠都没有喝这一瓶药水)

再分析1000瓶药水

如果4瓶药水的判断方法你看明白了,那么1000瓶药水就很容易理解了。

首先对1000瓶药水进行编码,0,1,2,3,4···,转成二进制,为

0000000000,
0000000001,
0000000010,
0000000011,
···

编码1000个数需要10个二进制位,故需要10只老鼠。

然后把1000瓶药水按照它们对应的编码分别喂给对应的小白鼠,最后小白鼠的状态编码就能标识出这1000瓶药水中哪一瓶是有毒的。

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值