返回首页 我的新博客

有意思

有1000瓶水,其中有一瓶有剧毒(假设哪怕一个毒药分子在里面也能致命),现在给你10只小狗在24小时内通过小狗试药的方式鉴定出来哪瓶药有毒。
情况1:假设小狗服药后2小时内即可判断是否中毒,鉴别方案有哪些?
情况2:假设小狗服药之后20小时才能判断是否中毒,鉴别方案又是什么?

         前天水母十大的一个帖子,挺有意思的,也算是温习一下上学期学的算法吧。其实算法课上倒是讲过类似的题目,是摔瓶实验,意思差不多,用二分法来做。同样,这个问题首先想到的就是二分法,2^10=1024>1000,实验小狗数目刚好够用,具体方案:先将1000瓶水均分成500和500两组,让1号小狗把其中一组的500瓶水都尝一下,2小时后,若该小狗死亡则说明毒水在这500瓶中,否则在另外500瓶中。将确认包含毒水的那组500瓶再均分两组,每组250瓶,让2号小狗把其中的一组的所有水都try一下,2小时后检查该小狗的身体状况。。。以此类推,每次操作都把问题规模缩小一半,所以叫二分。

         这个算法比较好理解,即使没学过相关课程的人,也能大致知道一二。不过对于情况2,虽然二分法依然可行,但作为一道题目,肯定不会让你拿一个办法对付两种情况。这两种情况的区别就在于毒药生效的时间,二分法的喂药量是最小的,但是每喂一轮就要等待毒药发作,2小时还能忍,20小时就不能忍了(小狗说:我被你们丫的拿来吃毒药,我还不能忍呢)。

         既然考虑到时间复杂度问题,最理想的情况就是同时把1000瓶水给喂下去,问题就在于如何区分。版上牛人给出的办法是用2进制的思想,把1000瓶水编号,从1、10、11、100……一直到1111101000(1000的二进制表示,正好10位),然后10条狗依次排开,分别对应从高到低10个数位,喂水的规则是:水瓶的二进制编号中有"1”的就喂给该数位对应的那条小狗,比如3号瓶二进制是11,就喂给最右边两条小狗。水都喂完了,等20小时,看看哪几条狗死了,活着的狗对应数位写0,死了的狗对应数位写1,得到一个二进制数,那么这个二进制数对应的那瓶水有毒。

         至于这个算法的证明,大概的思路如下:有毒的水,喂食的那几条小狗肯定都会死,剩下的都不会死,只需要说明唯一性就可以了。10条小狗死亡情况的可能性,正好是2^10=1024,跟水瓶一一对应还是没问题的。

posted @ 2009-10-16 13:57  buffer的blogs  阅读(292)  评论(0)    收藏  举报