2个瓶子100层楼
给2个一样的瓶子,其在>=x层楼的时候掉下来会碎,碎了就不能用,求最坏情况最少扔多少次才能确定x。
一个朴素的想法是第一个瓶子每10层扔一次,在第a次扔的时候碎了,确定区间为[10(a-1)+1,10a],然后从10(a-1)+1,一直扔到10a-1。最坏情况答案就是100层,要扔19次:10,20,30,40,50,60,70,80,90,100(碎),91,92,93,94,95,96,97,98,99(不碎但是可以确定是100)。
注意到这个算法在高楼层的时候不平均,可以让低楼层的时候间隔大一点,每次的间隔少1,这样保持每种最坏情况都是相同的。
比如初始间隔是14:
第1次用来确定[1,15],需要的是1+14次。
第2次用来确定[16,29],需要的是2+13次。
第3次用来确定[30,42],需要的是3+12次。
第4次用来确定[43,54],需要的是4+11次。
第5次用来确定[55,65],需要的是5+10次。
第6次用来确定[66,75],需要的是6+9次。
第7次用来确定[76,84],需要的是7+8次。
第8次用来确定[85,92],需要的是8+7次。
第9次用来确定[92,98],需要的是8+6次。
第10次用来确定[99,100],需要的是9+1次。
最坏情况就是15次,有可能还有其他解更好。
这里看出来是最后一次用得太少了,有可能可以再缩短间隔,但我建议还是写一个程序模拟这个过程,枚举初始的间隔,然后后面的每次把间隔减少1。
小白鼠试毒
有999瓶水,1瓶毒药,毒性在1小时后发作,把小白鼠毒死,求用多少只小白鼠才能在1小时内确定哪瓶是毒药。
最简单的是用1000只小白鼠,这样每只小白鼠只喝1种药,太浪费了,需要考虑可以喝混合物的情况。
这个是二进制编码的问题,类似数据通信原理里面学过的校验码的问题,把每瓶水/毒药编号从[1,1000],然后找9只小白鼠,
第1只小白鼠只喝二进制第1位是1的药,
第2只小白鼠只喝二进制第2位是1的药,
第3只小白鼠只喝二进制第3位是1的药,
...
第9只小白鼠只喝二进制第9位是1的药。
那么哪只小白鼠死了,就说明毒药的哪个二进制位为1。
为什么会对应到二进制?因为小白鼠只有生死两种状态,只能传递1个bit的信息,假如有4种状态,那么可以使用4进制。