提出问题:
有1000瓶水,其中有一瓶有剧毒(假设哪怕一个毒药分子在里面也能致命),现在给你10只狗在24小时内通过试药的方式鉴定出来哪瓶药有毒。
1,情况一:假设狗服药后2小时内即可判断是否中毒,鉴别方案有哪些?2,情况二:假设狗服药之后20小时才能判断是否中毒,鉴别方案又是什么?
情况一解答
——方法1[二分法]折半测试
对于情况一大多数人都能很快想到二分法解答即可。就是正好分为10层<2的10次方为1024>;这种筛选方法可以直接保证在20h内完成;
例如第一个2h可以选出位于哪个500瓶;第二个2h能知道位于哪250瓶中,依次进行...
——方法2[分层法]
1000除以10=100,每条狗喝不同的100种混合在一起的药,第一波就能知道位于哪个100瓶了;剩下的还有9只狗,再把100/9测试,依次迭代即可。或者采用折半法;分别对应的是8h 和 16h。
——方法3[一步到位法_二进制法]对应情况二的解答方法
情况二解答
分析:情况2才开始是个难点,根据题目要求我们可以直接想到,这是逼我们一步完成判断的想法;不可能还能进行第二阶段的测试。就是不会有_测试完了,看下情况,再准备下个阶段_这种情况出现。
那么我们可以直接想到,现在有10只狗子,我们的目标就是无视10只狗子的存活,实现对问题的成功解答,我们想下,只利用10只狗,但是每只狗都是独立鉴别100瓶的话,我们可以想到,这是完全不可能实现的,1只狗不可能在1步中鉴别出100瓶,连2瓶都做不多。
所以必须有交错控制,就类似我们的正交实验表的思想一样,一定是交叉试验。那么怎么实现交叉试验使得1000瓶药能够让10个狗子在一个阶段内进行辨别呢。聪明点的解题者已经完全理解了,我们要让1000瓶药对应1000个编码让10个狗子来组成这些编码识别出1000个可能性。
靠什么?二进制!
编码 0000000000 [10个零]——意义:不让任何狗来闻这个药;最后没有1只狗死,那么这个药有毒。
编码 0100000001 [第2,10位为1]——意义:让2号狗对这瓶药闻下,让10号狗闻下;最后只有2和10死了,其它8条或者,那么这个药有问题
编码0000000111[第8,9,10位为1]——意义:编码这个药_让8,9,10来闻下,最后若只有8,9,10三条狗死了,那么就是这个药有问题
编码N(0-1000)转成10位2进值 N -> num [xxxxxxxxxx;x = 0,1]
if(dog[num(which == 1)] is dead and dog[ num(which == 0)] is healthy): the num is 有毒: else:没毒
所以解决方法,对1-1000瓶药进行编号,将其编号转成二进制,为1的就让对应位置编号的狗子去嗅下即可。为0的就是对应位置编号的狗不用处理。
问题后的延伸思考:
如果是k瓶药有毒,如果这个阶段可以是n词,有p只狗,有N个总体的药。那么应该是个什么样的关系或者是解决思路?__解答下就是下面两种思路的扩展。
1,二进制;还会有3进制、四进制容易解决的例子出现;
2,可以出现2瓶药,或者3瓶药额情况。对应狗的设置,及能够在一步或者两步试出毒药的方法。
这个就留给聪明的读者去思考了;
另外还可以思考下:
_M,P,Q 的倒油问题;M,P为满桶体积的桶,Q为空的,最多可以提取多少种类 体积的油。
_扔鸡蛋问题;100层楼 用2 个鸡蛋试验鸡蛋的楼层承受层数。延伸的对应N层楼k个鸡蛋的(N,k)dp解法。