0%

兔子试毒问题

偶然看到一篇文章讲的是一个兔子试毒问题,问题描述如下:
有1000瓶药水,其中一瓶是毒药,喝上一滴一天后死亡,现在有一批兔子用于试毒,怎么花费最少的兔子,用最少的时间找出这批药水呢?

问题抽象

可以将问题抽象为时间与空间的决策,目标是在两者之间找出一个相对最优的方法。为此我们先想一下两种极端:

  • 追求极致的时间:需要一天和1000只兔子
  • 追求极致的空间:需要1只兔子,最坏需要1000天,最好只要一天(倒霉的兔子喝了第一滴就die了),平均下来就是500天,时间复杂度为O(n)

分治策略

分治策略中比较容易想到的就是二分查找,从这个算法联想到本问题,二分中的找数–>试毒中找那个毒药水。
怎么做呢?
我们先用两只兔子,将1000瓶分为两份,兔1灌500瓶(中的一滴),兔2灌另500瓶,一天后发现有只兔子die了,name毒药水肯定出在这500瓶中,然后我们再加一只兔子,再各喝一半,以此类推,直到剩下2瓶,此时一兔一瓶,ok了,谁死谁喝的毒药水。

然后我们还可以根据需求平衡一下,比如采用三分,四分…….等等,兔子越多,时间越短

更好的方法!

我也以为分治就是解决此问题的最优解法了,但是看了文章发现并非如此。有一种方法可以用10只兔子在一天内解决问题
作者提供了一个二进制编码的方式。1000瓶药,1000个编码,二进制的话就至少需要10位,然后我们进行编码0000000001为药水1我们给最后一只兔子喝下,0000000010,我们给倒数第二只喝下,0000000011,给后两只喝下……..也就时当前药水编码中为1的喝下,一天后观察去世兔子的编号,由于只有一瓶药水有毒,我们就可以还原出毒药水的编号,直接解决问题。