1. 程式人生 > >100層樓扔雞蛋,最快速度找出,哪層是雞蛋碎的臨界點

100層樓扔雞蛋,最快速度找出,哪層是雞蛋碎的臨界點

x*(x+1)/2=100層樓,x為最優解

640?wx_fmt=jpeg640?wx_fmt=jpeg

640?wx_fmt=png

 第二天

 

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

 

 

 

640?wx_fmt=png

題目:扔雞蛋問題

 

有2個雞蛋,從100層樓上往下扔,以此來測試雞蛋的硬度。比如雞蛋在第9層沒有摔碎,在第10層摔碎了,那麼雞蛋不會摔碎的臨界點就是9層。

問:如何用最少的嘗試次數,測試出雞蛋不會摔碎的臨界點?

640?wx_fmt=png

 

舉個栗子,最笨的測試方法,是什麼樣的呢?把其中一個雞蛋,從第1層開始往下扔。如果在第1層沒碎,換到第2層扔;如果在第2層沒碎,換到第3層扔.......如果第59層沒碎,換到第60層扔;如果第60層碎了,說明不會摔碎的臨界點是第59層。

在最壞情況下,這個方法需要扔100次。

640?wx_fmt=jpeg

640?wx_fmt=jpeg

 

640?wx_fmt=png

方法一:二分法

 

採用類似於二分查詢的方法,把雞蛋從一半樓層(50層)往下扔。

如果第一枚雞蛋,在50層碎了,第二枚雞蛋,就從第1層開始扔,一層一層增長,一直扔到第49層。

如果第一枚雞蛋在50層沒碎了,則繼續使用二分法,在剩餘樓層的一半(75層)往下扔......

這個方法在最壞情況下,需要嘗試50次。

640?wx_fmt=png

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

 

640?wx_fmt=png

方法二:平方根法

 

如何讓第一枚雞蛋和第二枚雞蛋的嘗試次數,儘可能均衡呢?

很簡單,做一個平方根運算,100的平方根是10。

因此,我們嘗試每10層扔一次,第一次從10層扔,第二次從20層扔,第三次從30層......一直扔到

100層

這樣的最好情況是在第10層碎掉,嘗試次數為 1 + 9 = 10次。

最壞的情況是在第100層碎掉,嘗試次數為 10 + 9 = 19次。

640?wx_fmt=png

不過,這裡有一個小小的優化點,我們可以從15層開始扔,接下來從25層、35層扔......一直到95層。

這樣最壞情況是在第95層碎掉,嘗試次數為 9 + 9 = 18次。

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

 

640?wx_fmt=png

 

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=png640?wx_fmt=jpeg640?wx_fmt=jpeg

640?wx_fmt=jpeg640?wx_fmt=jpeg

640?wx_fmt=png

假設最優的嘗試次數的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層。

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg640?wx_fmt=jpeg

640?wx_fmt=png

640?wx_fmt=jpeg

 

640?wx_fmt=png

方法三:解方程法

 

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 。

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg