總結 扔雞蛋問題 1

2021-08-28 15:17:41 字數 1808 閱讀 4413

最近我在知乎上看到了乙個扔雞蛋的問題[1],問題描述如下。在網上學習後,將相關知識整理如下。

有乙個 n 層的建築。如果乙個雞蛋從第 k 層及以上落下,它會碎掉。如果從低於這一層的任意層落下,都不會碎。

有 2 個雞蛋,用最壞的情況下實驗次數最少的方法去找到k, 返回最壞情況下所需的實驗次數。

拓展:若有m個雞蛋,返回最壞情況下所需的實驗次數。

測試用例:

m = 2, n=100 → t = 14

m = 2, n = 36 → t = 8

定義用 m 個蛋在 n 層大樓上最壞情況下確認 k 的所需試驗次數,記為 f(n, m),易知 m >= 1 ,f(0, m) = 0,f(n, 1) = n

我們可以把任何一種策略都看成乙個決策樹, 每一次扔瓶子都會有兩個子節點, 對應碎與不碎的情況下下一步應該扔的樓層。

那麼, 策略的一次執行, 是樹中的一條從根往下走的路, 當且僅當這條路上出現過形如 k 層沒碎 與 (k+1)層 碎了的一對節點時, 路停止, 當前節點不再擴充套件。那麼要找的是這麼一棵樹, 使得所有路裡最長者盡量短, 也即, 要找乙個最矮的決策樹。

再看乙個節點處, 選擇樓層時會發生什麼。容易看出, 選擇的樓層如果變高, 那麼"碎子樹"高度不減, "不碎子樹"高度不增。同樣的, 選擇的樓層變矮的話, "碎子樹"高度不增, "不碎子樹"高度不減。

這時候答案很明顯了: 為了使兩子樹中高度最大者盡量小, 我們的選擇應當使兩子樹高度盡量接近.最終希望的結果是, 整個二叉樹盡量像乙個滿二叉樹。

假設第一次在根節點上, 我們選擇扔k層, 其"碎子樹"的高度顯然是k - 1。為了考慮不碎子樹的高度, 設不碎後第二次扔m層(顯然m > k ), 則這個新節點的碎子樹高度為 m - k - 1, 不碎子樹高度仍然未知, 但按照滿二叉樹的目標, 我們認為它與碎子樹相同或少1就好。那麼在根節點上的不碎子樹的高度就是m -k-1 + 1, 令它與碎子樹高度相同, 於是: m - k - 1 + 1 = k - 1 => m = k + k - 1。

也即, 如果第一次扔在k層, 第二次應該高 k-1 層, 這可以有直觀一點的理解:每扔一次, 就要更保守一些, 所以讓區間長度少1. [1, k) -> [k + 1, 2k - 1)。用類似剛才的分析, 可以繼續得到, 下一次應該增高k - 2, 再下一次應該增高k - 3。

可以得出,此時有 k + (k-1) + (k-2) + …… + 1 = n,所求得的k值即為 f(n, 2) 的值。

考慮在第w層扔下雞蛋,情況有兩種:

綜上所述,由上述兩種情況可知,最壞情況下的最小值 f(n, m) = min + 1 | 1<=i<=n } 。此演算法時間複雜度為o(mn2),由於當 m>n 時,令 m=n 不影響結果,則o(mn2)=o(n3)。空間複雜度為o(n)。

下限的優化

考慮最壞情況,如上所言,此二叉樹的葉子結點有(n+1)個,則樹的高度至少為⌈log2(n+1)⌉+1,而二分尋找的最壞情況也為⌈log2(n+1)⌉。所以⌈log2(n+1)⌉是乙個可達的下限。換而言之,對任意的n,無論m取何值,f(n, m)的值均不會小於⌈log2(n+1)⌉。一旦 m>=⌈log2(n+1)⌉,可直接輸出⌈log2(n+1)⌉,時間複雜度降為o(n2 log n)。

[1]一幢 200 層的大樓,給你兩個雞蛋。如果在第 n 層扔下雞蛋,雞蛋不碎,那麼從第 n-1 層扔雞蛋,都不碎。這兩隻雞蛋一模一樣,不碎的話可以扔無數次。最高從哪層樓扔下時雞蛋不會碎?

[2]problem of two eggs

[3]教你徹底理解動態規劃——扔雞蛋問題 drop eggs2

[4]優化,再優化!——從《鷹蛋》一題**對動態規劃演算法的優化

扔雞蛋問題

因為就乙個雞蛋,所以,我們很容易就可以想到從第一層開始扔就可以了,直到碎,說明這是n 1層。這裡當然也可以按照第乙個問題的方法來實現,即從第一層開始向上,直到摔碎為止,但是這種方法顯然是低效的。方法二 二分查詢 當時就想到了使用這種方法,即採用二分查詢的思路,第一次在50層扔 如果碎了,那麼從第一層...

扔雞蛋問題

因為就乙個雞蛋,所以,我們很容易就可以想到從第一層開始扔就可以了,直到碎,說明這是n 1層。這裡當然也可以按照第乙個問題的方法來實現,即從第一層開始向上,直到摔碎為止,但是這種方法顯然是低效的。方法二 二分查詢 當時就想到了使用這種方法,即採用二分查詢的思路,第一次在50層扔 如果碎了,那麼從第一層...

扔雞蛋問題

標籤 演算法 初始問題 在100層樓裡,給定2個雞蛋,在安全樓層以上的樓扔雞蛋會碎。設計一種方案,測試哪層樓是最高安全樓層,要求測試次數最少。思路 這是典型的動態規劃問題。假設 f n 表示從 n 層樓找到摔雞蛋不碎安全樓層的最少判斷次數。假設第乙個雞蛋第一次從第 i 層扔下,如果碎了,說明安全樓層...