题目链接:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/08.02.md
对于第一题是海盗分金,第一个海盗能得到多少呢?97(惊讶吧。。。。)小时候做这个题都没思路,学了博弈论的逆向推导才知道怎么搞,具体分析是这样的:
1、对于最后一个人来说,他对于对于谁的提议都会否定,因为其他人都死掉了他自然可以得到100颗宝石。
2、第四个人呢当然知道他这样想(人们都很聪明),所以如果他前面人都死了,他自己也会死,因为不论提什么方案,最后一个人不同意都不会得到更坏的结果,所以第四个人要尽可能保证前面有人活着。
3、第三个人也知道倒数两个人的想法,所以他只要前面人都死掉,可以要100颗宝石,第四个人一定同意他,加上他自己的一票超过半数了。
4、第二个人知道那三个人这样想,为了可以得到宝石,他需要给第五个和第四个人各一颗宝石,收买他们,这样可以获得加上自己的3票,不需要给第三个人因为第三个人一定不会投他的,即使投,也不必要收买他,因为已经足够赢了,第二个人将给自己98颗。
5、第一个人也知道前面人的思维方式,他将分给第三个人1颗,因为如果第三个人不同意,第二个人做决定是不会分给他任何宝石的,所以第三个人一定会同意(有比没有好啊),那还差一票才3票大于一半,所以还可以收买第四个人或者第五个人,因为第二个人会出1颗收买他们,可以随便选一个人去收买,要出2颗宝石收买,这样多一个比少一个好,一定也会同意的。所以第一个人的最大收益是97颗宝石。(由于现实中不是每个人都这么理性。。。。所以这就是个理论分析)
第六题 8瓶水,找出唯一一瓶的有毒,这就是二分搜索,首先随机拿四瓶混合起来,给小鼠喝(真倒霉。。。),死掉了就是在这四瓶里面,否则就在剩余四瓶里面,再把范围内的四瓶分2份,继续这样测试,就搞出来了,log2(8)= 3,所以三次。
第八题 也是验证有毒的,但是5分钟才能有效果,而且问5分钟能检测出多少,所以只能喝一次。用的也跟二分的思想差不多,把解空间分开。
通过二进制覆盖解空间,比如有2只鼠,4瓶水编号(0~3),一瓶有毒,第0瓶都不喝,第一只喝第一瓶,第二只喝第二瓶,两只都喝第三瓶,那么00(二进制)代表编号0的有毒,10代表第一瓶有毒(1代表死掉,0活着),01代表第二瓶有毒,11代表第三瓶有毒。
那么对于5只就可以覆盖2^5瓶,也用同样方法,比如00101,就让第一只和第三只一起喝编号10的水,这样就可以根据哪只的死亡,对应瓶编号。
这个题目阿里的有题类似的是给16瓶,1瓶有毒,问至少几次可以分辨出14瓶没毒的。答案3次。
方法也差不多:
A,B,C对应的框表明三只鼠喝哪些水,如果AB死了,C没死,则2或者14有一瓶有毒(哪一瓶不确定),则其它14瓶没毒,AB死掉了说明共同喝的2,6,10,14可能某个有毒,而C没死,说明3只共同喝的6,10没毒,则2或14有毒,其它的情况也是一样分析。