100層樓扔雞蛋,最快速度找出,哪層是雞蛋碎的臨界點
x*(x+1)/2=100層樓,x為最優解
第二天
題目:扔雞蛋問題
有2個雞蛋,從100層樓上往下扔,以此來測試雞蛋的硬度。比如雞蛋在第9層沒有摔碎,在第10層摔碎了,那麼雞蛋不會摔碎的臨界點就是9層。
問:如何用最少的嘗試次數,測試出雞蛋不會摔碎的臨界點?
舉個栗子,最笨的測試方法,是什麼樣的呢?把其中一個雞蛋,從第1層開始往下扔。如果在第1層沒碎,換到第2層扔;如果在第2層沒碎,換到第3層扔.......如果第59層沒碎,換到第60層扔;如果第60層碎了,說明不會摔碎的臨界點是第59層。
在最壞情況下,這個方法需要扔100次。
方法一:二分法
採用類似於二分查詢的方法,把雞蛋從一半樓層(50層)往下扔。
如果第一枚雞蛋,在50層碎了,第二枚雞蛋,就從第1層開始扔,一層一層增長,一直扔到第49層。
如果第一枚雞蛋在50層沒碎了,則繼續使用二分法,在剩餘樓層的一半(75層)往下扔......
這個方法在最壞情況下,需要嘗試50次。
方法二:平方根法
如何讓第一枚雞蛋和第二枚雞蛋的嘗試次數,儘可能均衡呢?
很簡單,做一個平方根運算,100的平方根是10。
因此,我們嘗試每10層扔一次,第一次從10層扔,第二次從20層扔,第三次從30層......一直扔到
這樣的最好情況是在第10層碎掉,嘗試次數為 1 + 9 = 10次。
最壞的情況是在第100層碎掉,嘗試次數為 10 + 9 = 19次。
不過,這裡有一個小小的優化點,我們可以從15層開始扔,接下來從25層、35層扔......一直到95層。
這樣最壞情況是在第95層碎掉,嘗試次數為 9 + 9 = 18次。
假設最優的嘗試次數的x次,為什麼第一次扔就要選擇第x層呢?
這裡的解釋會有些燒腦,請小夥伴們坐穩扶好:
假設第一次扔在第x+1層:
如果第一個雞蛋碎了,那麼第二個雞蛋只能從第1層開始一層一層扔,一直扔到第x層。
這樣一來,我們總共嘗試了x+1次,和假設嘗試x次相悖。由此可見,第一次扔的樓層必須小於x+1層。
假設第一次扔在第x-1層:
如果第一個雞蛋碎了,那麼第二個雞蛋只能從第1層開始一層一層扔,一直扔到第x-2層。
這樣一來,我們總共嘗試了x-2+1 = x-1次,雖然沒有超出假設次數,但似乎有些過於保守。
假設第一次扔在第x層:
如果第一個雞蛋碎了,那麼第二個雞蛋只能從第1層開始一層一層扔,一直扔到第x-1層。
這樣一來,我們總共嘗試了x-1+1 = x次,剛剛好沒有超出假設次數。
因此,要想盡量樓層跨度大一些,又要保證不超過假設的嘗試次數x,那麼第一次扔雞蛋的最優選擇就是第x層。
方法三:解方程法
x + (x-1) + (x-2) + ... + 1 = 100
這個方程式不難理解:
左邊的多項式是各次扔雞蛋的樓層跨度之和。由於假設嘗試x次,所以這個多項式共有x項。
右邊是總的樓層數100。
下面我們來解這個方程:
x + (x-1) + (x-2) + ... + 1 = 100 轉化為
(x+1)*x/2 = 100
最終x向上取整,得到 x = 14
因此,最優解在最壞情況的嘗試次數是14次,第一次扔雞蛋的樓層也是14層。
最後,讓我們把第一個雞蛋沒碎的情況下,所嘗試的樓層數完整列舉出來:
14,27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100
舉個栗子驗證下:
假如雞蛋不會碎的臨界點是65層,那麼第一個雞蛋扔出的樓層是14,27,50,60,69。這時候啪的一聲碎了。
第二個雞蛋繼續,從61層開始,61,62,63,64,65,66,啪的一聲碎了。
因此得到不會碎的臨界點65層,總嘗試次數是 6 + 6 = 12 < 14 。