100層樓扔兩個雞蛋問題

2022-09-17 04:33:12 字數 1727 閱讀 3579

解釋:兩個雞蛋一樣,只有在達到某個樓層高度時,才會摔碎。可以假設這個摔碎臨界樓層是n。

可見,用二分法結果很不穩定,特別是n小於50時最糟糕(甚至會比第一種直接遍歷的還要多一次)。n越大越好找,需要嘗試的次數越少。

如果這個題目換成雞蛋個數不限制,那就是用二分法最快了。

當最高樓層為100時,可列出不等式:最高可能嘗試到的樓層x*(x+1)/2 > 100,解出x=14次。這就是最穩定的最快尋找到該樓層的扔雞蛋次數。也就是說第一次扔雞蛋要從14樓開始扔。14+13+12+11+...+2+1 = 105層,也就是14次嘗試一定可以在1-105層中找到那個第n層。推出了公式x*(x+1)/2後,要想程式設計求任意總樓層條件下,就都很方便了。

在我們程式設計解決問題的過程中,如果遇到最優問題的時候,往往可以先嘗試一下動態規劃的方法。而動態規劃的方法,首要的我們要找到構成這個最優問題的最優子問題。所以,下面的分析,我們首先嘗試動態規劃的方法,如何解決這個問題,這也是典型的程式設計師的思路;其次,在眾多的問題當中,有不少可以直接歸結為數學方程式,如果我們能夠寫出數學方程式,那麼,答案將是更加的簡潔、美妙(比如上一種方法推導出來的公式)。

所以,當第乙個雞蛋,由第i個位置落下的時候,要嘗試的次數為f[i]= 1 + max(i - 1, f[n-i])用max是確保一定可以在這麼多次內找到。那麼對於每乙個i對f(i)進行比較,非最小的f(i),就是f的值。狀態轉移方程如下: f = min f[i] = min(1 + max(i - 1, f[n-i]) ) 其中: i的範圍為(1, n), f[1] = 1 完畢。

推廣動態規劃的方法,可以推廣為n層樓,m個雞蛋。如下分析: 假設f表示n層樓、m個雞蛋時找到最高樓層的最少嘗試次數。當第乙個雞蛋從第i層扔下,如果碎了,還剩m-1個雞蛋,為確定下面樓層中的安全樓層,還需要f次,找到子問題;不碎的話,上面還有n-i層,還需要f[n-i,m]次,又乙個子問題。 狀態轉移方程如下: f = min(1 + max(f, f) ) 其中: i為(1, n), f = 1

1 #include 2 #include 3 #include 4

5using

namespace

std;

6const

int n = 55;7

const

int m = 1010;8

int dp[n][m];//

剩餘i個雞蛋在j層樓進行的最少次數

9int

n, m;

1011

void

init()

1219

for(int i = 1; i < m; ++i)

20 dp[1][i] =i;

21for(int i = 2; i < n; ++i)

22for(int j = 2; j < m; ++j)

23for(int k = 1; k < j; ++k)//

最壞情況的最少次數,碎和沒碎兩種情況取最大值

24 dp[i][j] = min(dp[i][j], max(dp[i][j-k]+1, dp[i-1][k-1]+1

));25}26

27int

main()

2838

return0;

39 }

100層樓扔兩個雞蛋

兩個軟硬程度一樣但未知的雞蛋,它們有可能都在一樓就摔碎,也可能從一百層樓摔下來沒事。有座100層的建築,要你用這兩個雞蛋確定哪一層是雞蛋可以安全落下的最高位置。可以摔碎兩個雞蛋。最少需要幾次測試,才能得到摔碎雞蛋的樓層?方案如何?問題轉化 兩個雞蛋,扔k次,最多測試多少層樓?假設第乙個雞蛋從m層扔下...

100層樓摔雞蛋問題

reference 題目 有一棟100層高樓,從某一層開始扔下的玻璃杯剛好摔壞,現有兩個玻璃杯,最少幾次能找到那一層?首先我要對題目的表述提點意見。這是乙個很有歧義的表述方式,容易誤導人向概率的方向去思考。比如說,我可以回答 最少一次能找到那一層 我就拿個杯子,從一樓起一層一層的摔。從概率上講,有可...

百層樓扔棋子問題

有乙個100層高的大廈,你手中有兩枚相同的玻璃棋子。從這個大廈的某一層扔下圍棋子就會碎。用你手中的這兩枚圍棋子,找出乙個最優的策略,來得知那個 臨界 層面 第一次應該從哪層開始扔?以你的方案,最壞的情況多少次可以測出臨界層?這是一道google的面試試題,具體 不得而知,網上有無數解法,諷刺的是,g...