這是一道leetcode上面的題:
開始看到真的一頭霧水,看了很多題解。最後恍然大悟只要明白進製這題也就不難了。
下面以示例1參考:從1000個桶bucket中找到其中一桶有毒的,問在規定的時間內最少需要幾頭豬?
桶狀態bucket有且只有兩種:無毒1、有毒0。
豬的狀態state有且只有兩種:存活1、死亡0。
有 bucket0 state0 & bucket1 state1
------做一次實驗試出毒藥,找出1000桶bucket的毒藥至少需要多少只豬呢?-------
h(x) = log21000 = 9.96 10頭
這也是夏農熵的公式。
1000桶按二進位制(0/1)編碼。每頭豬給喂當前當前進製位上為1的桶的所有液體,如豬1喂(1,3,5,7.....),豬2喂(2,3,6,7,10....)。
假設第666桶bucket是有毒的。
那麼結果必然是只有(1,3,6,7,9)號豬是活的,(2,4,5,8,10)號豬死了。那麼豬死了就把對應的二進位制位置為1,二進位制轉換1010011010 --------- 666。所以666桶有毒。
--------------那麼可以做4次試驗,找出1000桶bucket的毒藥至少需要多少只豬呢?-------------
1、依然是把1000個桶bucket按照5進製分組;此時只需要5bit的資訊。
2、每頭豬給喂當前進製位上為1的桶的所有液體(0-15分鐘),當前進製位上為2的桶的所有液體(15-30分鐘),當前進製位上為3的桶的所有液體(30-45分鐘),當前進製位上為4的桶的所有液體(45-60分鐘)。
3、那麼乙隻豬有5種狀態,15分鐘死亡(state1),30分鐘死亡(state2),45分鐘死亡(state3),60分鐘死亡(state4),最終存活(state0);
h(x) = log51000 = 4.29 5頭
最好的情況,5進製轉換 11111 ------- 781,第一次試驗就知道了781隻桶有毒。
同樣假設第666桶有毒,那麼結果必然是(1號、3號、5號)豬1輪亡,2號豬3輪亡,4號豬經過四輪後存活。5進製轉換10131 ------ 666 ,結果是666號桶有毒。
理解了這個編碼就變得非常簡單了
class這裡試驗次數+1,才是state的狀態。最後一種狀態可以在前面結果全部取反時,直接得到。solution
}
方案是沒問題的,至於為什麼這樣做是最優的。夏農大佬早已經給出了答案,任何想逾越這個極限去解決問題的人最後都會被證明是徒勞的。
公式簡單,但其背後關於進製的轉換以及所蘊含的資訊理論知識是值得思考的。
參考:solution/xiao-song-man-bu-dai-ma-bu-zhong-yao-xue-poet/
458 可憐的小豬
有1000只水桶,其中有且只有一桶裝的含有毒藥,其餘裝的都是水。它們從外 起來都一樣。如果小豬喝了毒藥,它會在15分鐘內死去。問題來了,如果需要你在一小時內,弄清楚哪只水桶含有毒藥,你最少需要多少只豬?回答這個問題,並為下列的高階問題編寫乙個通用演算法。高階 假設有 n 只水桶,豬飲水中毒後會在 m...
458 可憐的小豬
有1000只水桶,其中有且只有一桶裝的含有毒藥,其餘裝的都是水。它們從外 起來都一樣。如果小豬喝了毒藥,它會在15分鐘內死去。問題來了,如果需要你在一小時內,弄清楚哪只水桶含有毒藥,你最少需要多少只豬?回答這個問題,並為下列的高階問題編寫乙個通用演算法。高階 假設有 n 只水桶,豬飲水中毒後會在 m...
458 可憐的小豬
有 buckets 桶液體,其中 正好 有一桶含有毒藥,其餘裝的都是水。它們從外 起來都一樣。為了弄清楚哪只水桶含有毒藥,你可以喂一些豬喝,通過觀察豬是否會死進行判斷。不幸的是,你只有 minutestotest 分鐘時間來確定哪桶液體是有毒的。餵豬的規則如下 選擇若干活豬進行餵養 可以允許小豬同時...