小鼠試毒問題(二進制)

1000桶酒,其中1桶有毒。而一旦吃了,毒性會在1周後發作。問最少需要多少隻老鼠可在一週內找出毒酒?

如題。

分析思路:
要用盡可能少的老鼠完成相對大的任務量,要想到把問題進行對數分解
從而不難想到 210=10242^{10}=1024 這個數量關係。

解法一:
二進制編碼。

首先對1000桶酒按照1~1000進行二進制編碼,因爲 2102^{10} = 1024 > 1000,因此需要10位二進制。
故只需要取10只老鼠,每隻老鼠只喝其對應位數爲1的編號的酒。

然後給10只老鼠按以下編碼:
第一隻 0000000001
第二隻 0000000010
第三隻 0000000100

第十隻 1000000000

結果舉例:編號爲1000100011的酒是毒酒。
則對應喝酒的只有第一隻,第二隻,第六隻,第十隻死亡。

故最後可從哪幾只老鼠死亡來判斷毒酒的編號是多少。

通用公式:
N桶酒,老鼠所能表示的狀態數目爲M,則需要的老鼠個數爲: K=logMNK =log_M{N}

而具體實驗的操作方法爲:
1.每種狀態按照 M 進制進行編碼,編碼長度爲 K
2.每個老鼠分別去拿自身的 M 中狀態去實驗 N 的 M 進制編碼的某一位
3.所以 K 個老鼠,等同於是 K 長度 M 進制的對應的每一位
4.這樣試驗完後,就確定了每一位上面的數字,找到對應的那種狀態就好。

解法二:
二分法。

具體喝法如下:
第一隻:1-500
第二隻:1-250,501-750
第三隻:1-125,251-375,501-625,751-875

因爲2102^{10}>1000 , 292^{9}<1000

所以最少需要10只老鼠。


觸類旁通:

初級版問題——每隻只能實驗一次

即上題。因爲每隻老鼠只能實驗一次,所以,每隻老鼠身上有兩種狀態一死亡或者存活,而酒中有毒的信息總量爲1000,即每桶酒都有可能有毒。

所以需要的編碼長度爲:log21000log_ 2 {1000} 向上取整得到10

中級版問題一一每隻可以實驗多次

10000桶酒,其中1桶是毒酒;48小時後要舉行酒會;毒酒喝下去會在之後的第23-24小時內毒死人(時間確定);國王決定用囚犯來試酒,不介意囚犯死多少,只要求用最少的囚犯來測試出哪一桶是毒酒,問最少需要多少囚犯才能保證找出毒酒?

根據題目要求,對於每個囚犯,是可以實驗24次的,即第0小時喝,然後第1小時再喝,。。。如果第K小時死亡,則是因爲第K-24(上取整)小數喝的酒導致的。

這樣的話,每個人就含有了25個狀態,即24小時分別每個小時死亡,外加最後沒有死。

所以需要的囚犯數爲 log2510000log_{25}{10000} = 3, 即將10000桶酒按照25進制編碼進行編碼,是一個三位數長度的25進制數。

然後三個人分別第i小時去喝對應位數上編碼爲i的所有酒,最後就能確定下來具體喝哪一桶酒。

類似的題:
1000桶水,其中一桶有毒,豬喝毒水後會在15分鐘內死去,想用一個小時找到這桶毒水,至少需要幾頭豬?

解:每頭豬有5種狀態,所以5頭豬即可完成編碼。

高級問題—-不止一桶有毒

不止一桶有毒的情況下,其實非常地複雜。

1000桶水中兩桶有毒,豬喝毒水後會在15分鐘內死去,想用一個小時找到毒水,至少需要幾隻豬?如何實現?

因爲有兩桶有毒,所以信息量爲:N=C10002N = C _ {1000}^{2}種情況。
每隻豬身上有5種狀態,所以最低有:log5N=9log_{5}{N}= 9
但是這個只是理論下界,因爲豬死亡是不能夠區分出,是被一桶毒水毒死的,還是兩桶毒水。

假設豬死亡的狀態可以區分出來/或者兩種毒水需要混合纔能有毒性的話,那麼做法是,將這1000桶毒水兩兩混合,一共 N=C10002N = C _ {1000}^{2} 種組合,然後將這些組合按照5進制進行編碼。然後9只豬就可以區分出來了。

而對於這道題來說,不止一桶水有毒的情況,就是先用交叉法再用進製法。
即10只豬每隻喝100桶,然後按照死一隻還是死兩隻進行分開討論。

具體如下:
1.給每隻豬喂對應個位數編號的水,這樣第一個15分鐘後肯定最多死兩隻豬。

2.1.如果死了兩隻豬的話,則同時確定了兩個[100桶水裏有一桶水有毒]。問題簡化成兩個[100桶水裏有一桶水有毒],45min確定哪兩桶。
將剩下八隻豬平均分開,思考可以用幾進制的四位數至少可以表示到100,分別確定這桶水。因爲 444^{4}>100,剛好每隻豬剩4種狀態,所以兩步一共需要10只豬。

2.2 如果僅死一隻豬的話,問題變成100桶水裏兩桶有毒,45min確定哪兩桶。
利用1思路,給剩下的豬每隻喂12桶水。

2.2.1若死兩隻豬(此時還剩下7只豬),則問題簡化成兩個[12桶水一桶有毒],30min確定。
因爲 333^{3}>12,所以剛好將剩下的豬分成33兩組。

2.2.2若死一隻豬(此時還有八隻豬),問題變成12桶水裏兩桶有毒,30min確定哪兩桶。
利用1思路,給剩下的豬每隻喂2桶水。

2.2.2.1若死兩隻豬(此時還有六隻豬),問題變成兩個[2桶水裏一桶有毒],15min確定哪兩桶。

2.2.2.2若死一隻豬(此時還有七隻豬),問題變成2桶水裏兩桶有毒,15min確定哪兩桶。

故而此方法10只是最多的。


可利用 二進制編碼 解法的又一種題目:

500張多米諾骨牌整齊地排成一列,依順序編號爲1、2、3…499、500。第一次拿走所有奇數位置上的骨牌,第二次再從剩餘骨牌中拿走所有奇數位置上的骨牌,依此類推。請問最後剩下的一張骨牌的編號是多少?

如題。

所有骨牌都可以用一個9位的二進制編碼來標記。

題目中,第1次取牌抽走了所有末位是1的牌,剩餘末位爲0的牌;第2次抽牌則在第一次剩餘的牌中抽走倒數第二位爲1的牌…

以此類推,第k次抽牌留下的是形如XXX…X000…0(k個0)的牌。

因此,最後一次抽牌留下的是二進制編碼爲100000000,即十進制256的牌。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章