Google面試題-高樓扔雞蛋問題


本文由 @lonelyrains 出品。轉載請注明出處。 
文章鏈接: http://blog.csdn.net/lonelyrains/article/details/46428569


高樓扔雞蛋問題   這個問題非常有名了  早幾年之前面試的時候都遇到過,可是當時也確實沒搞清楚怎么做,后來也沒管了。今天網上偶然碰到,打算趁這個機會徹底搞清楚,就寫一篇博文吧。

網上非常多資料,但我感覺都不太易懂,每一步的推導是為什么。

所以我這里僅僅想寫一種比較簡單、比較完整的推演流程。


題目描寫敘述: (挑了一個比較嚴謹的描寫敘述。問題描寫敘述嚴謹非常重要。不然會影響解題思路)
一幢 100 層的大樓,給你兩個雞蛋. 假設在第 n 層扔下雞蛋,雞蛋不碎,那么從前 n-1 層扔雞蛋都不碎.
這兩僅僅雞蛋一模一樣,不碎的話能夠扔無數次. 已知雞蛋在0層扔不會碎.
提出一個策略, 要保證能測出雞蛋恰好不會碎的樓層, 並使此策略在最壞情況下所扔次數最少.


問題分析:


1)最壞情況下所扔次數最少。比較繞口。想表達的意思是。在不明白知道哪一層會碎的情況下。要找到一種策略,通過最少的試驗次數,得到臨界樓層(恰好不會碎的樓層)。不明白知道。就須要考慮最糟糕的情況,並且這樣的策略與其它策略相比是最糟糕的情況下,最少的試驗次數。


2)假設一種扔法:第一個雞蛋,從50樓扔下去。

假設碎了,第二個雞蛋必須從1~49層逐層試驗。假設第i層為臨界層。且i≤49,這個時候,要試驗的總次數是1 +(i - 1)。由於必須保證在沒找到臨界樓層之前,雞蛋不能碎。假設沒碎,則第一個雞蛋能夠接着從75層扔。

由於即使這次碎了,還有個雞蛋,能夠繼續逐層試驗。對第一個雞蛋的繼續從中間分,就比較合理。


3)假設到代數:假設第一枚雞蛋扔下去的層數為i,則碎了的情況,須要扔的總次數最糟糕的情況是1 + ( i - 1 );假設沒碎,剩下的兩個雞蛋都在,須要扔的次數一定為1 + 用兩枚雞蛋來解決剩下的100 - i層的次數(這個問題跟原題是一樣的。可是層數少了一些)。也就是 假設用f ( 100 )表示100層的最壞情況下的最少次數,那么從第i層扔雞蛋的最糟糕的試驗次數是 1+ Max( i - 1, f ( 100 - i ) ),Max表示這兩者之間的最大值,是最最糟糕的情況了。

 而 f ( 100 ) 就是對全部從1到100的全部i里。 1+ Max( i - 1, f ( 100 - i ) )的值最小的那個。


4)迭代公式: f ( 100 ) = Min ( 1 + Max ( i - 1, f (100 - i ) ) ) .   當中Max是針對的 i-1、 f ( 100 - i ) 兩者 。 而Min是針對的全部的從1到100的i。


5)初始狀態: 假設有一層,從第一層扔下去,無論碎不碎。最糟糕的情況也僅僅須要推斷一次。 即 f ( 1 ) = 1。而如題所述,第0層不會碎,則 不用扔也知道,即f(0) = 0。


6)終於結論:題目變成了分析一個迭代公式的值。翻譯成了計算機語言,剩下的就能夠交給計算機了。

不須要知道怎么一步步算,這不應該是人干的事。僅僅須要知道已經變成了能夠循環遞歸的算式,能夠交給計算機即可了。

// 實現代碼   <a target=_blank href="http://blog.csdn.net/lonelyrains">blog.csdn.net/lonelyrains</a>

#include <stdio.h>

// #define MAX((a),(b)) (a)>(b)?

(a):(b) //注意這里也是常考的一點,應該寫成以下的形式 #define MAX(a,b) ((a)>(b)?(a):(b)) int fun ( int layer ) { if ( layer <= 0 ) { return 0; } if ( layer == 1 ) { return 1; } int min = layer; // 一棟layer層的大樓試驗次數肯定不可能超過layer次。 int temp; for ( int i = 1; i <= layer; i++ ) { temp = 1 + MAX(i-1, fun( layer - i ) ); if( min > temp ) min = temp; } return min; } int main() { int layer = 19; printf("%d",fun(layer)); return 0; }


用上面的代碼測試了一下,給layer賦值19。即針對一棟19層的大樓來算最壞情況的最少次數。就要非常長時間才干出結果了(果然18層是地獄)....    

7)其它擴展:

① 問題的解法不止這一種描寫敘述,並且不一定要交給計算機算。由於這樣遞歸算。計算機要累死了。能夠優化到用非常easy的數列求和公式得到。

關於怎么來的,有兩種思路。能夠參考以下的第二個參考鏈接給出的基於意義的理解。這是一種思路。可是比較難理解。第二種。就是純粹的組合數學方法。將迭代公式轉換成通項公式,這個問題還沒找到有人這樣寫過,可是絕對能夠有。

② 問題能夠擴展為一棟n層的大樓,有m個雞蛋。甚至不止一棟,而是p棟。 無論怎么樣擴展,問題都能夠歸為找迭代公式。

這個思路就是動態規划的精髓。


8)參考鏈接:

http://www.zhihu.com/question/19690210

http://blog.csdn.net/linj_m/article/details/9792821


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM