一、題目:
有一棟樓共100層,乙個雞蛋從第n層及以上的樓層落下來會摔破, 在第n層以下的樓層落下不會摔破。給你2個雞蛋,設計方案找出n,並且保證在最壞情況下, 最小化雞蛋下落的次數。
二、思路:
先假設,最小的次數為x次。
首先在x層摔,那麼會出現兩個結果:
1、碎了,為了找出那一層碎了,第二個雞蛋必須從1~x-1進行遍歷的摔
2、沒碎,那麼第二次就在x+(x-1)樓層摔。
為什麼是x+x-1樓層呢?3、如果在x+(x-1)樓碎了,那麼同1,遍歷x+1~x+(x-1)-1首先我們已經假設了通過x步我們就能得到答案,現在我們在x層已經用了一次了,那麼就只剩下x-1步了。所以我們選擇x+(x-1)層,如果碎了,我們就能通過x-2步,遍歷x+1~x+(x-1)-1的所有樓層。
4、沒碎,那麼同2,就在x+(x-1)+(x-2)層摔
… 最後我們將會得出這樣乙個樓層公式x+(x-1)+(x-2)+…+1 = x(x+1)/2。
這個公式有什麼意義呢?
有, x(x+1)/2 >= 100,這樣才能順利的解除x。
有人說,x(x+1)/2 = 99就可以,如果雞蛋在99層都沒碎,那麼必定是100層。我想說誰告訴你記得一定會碎!
那麼我們就順利的解除 x=14。
三、擴充套件
此題還有乙個擴充套件,就是為n個雞蛋從m層摔找出最小值。
那就不是很好手解了,所以寫了**,使用動態規劃原理。動態規劃式子如下:
f[n][m] = 1+max(f[n-1][k-1],f[n][m-k]) k屬於[1,m-1]解釋下原理:
1、當手裡有n個的時候,雞蛋從k層往下摔,如果破了,那麼手裡只有n-1雞蛋了,那麼就需要測試f[n-1][k-1]樓層。或者更通俗好理解點的,我們運用2個雞蛋100樓層的題目舉例子。以上式子變為:f[2][m] = 1+max(f[1][k-1],f[2][m-k])
那麼當手裡有2個雞蛋的時候,在k層摔,碎了。那麼現在手裡也就只有乙個雞蛋了,此時我們必須遍歷1~k-1找出第一次碎的樓層。所以為1+f[1][m-k],前面的1代表在k層的操作。
2、沒破,那麼手裡還有n個雞蛋,那麼需要測試k+1~m這些樓層。
此時我想問下,當手裡有2個雞蛋測試1~m-k層和手裡有2個雞蛋測試k+1~m有什麼區別?
有人說有,因為樓層越高越容易碎,那其實是你個人的想法罷了。其實並沒有區別,所以第乙個公式可以寫為f[n][m-k]。
最後附上**,為了理解方便,而不必從陣列從0開始而困擾,這裡就空間多開了點,所以如果拿去用的話,可以優化下:
public
class eggs
for(int n=2; n<=egg; n++)}}
return f[egg][num];
}public
static
void
main(string args)
}
參考文章:
100層樓2個雞蛋,如何得知雞蛋能承受幾層的撞擊
兩個雞蛋100層樓(dp)
2個雞蛋從100層摔(N個雞蛋從M樓層摔)
一 題目 有一棟樓共100層,乙個雞蛋從第n層及以上的樓層落下來會摔破,在第n層以下的樓層落下不會摔破。給你2個雞蛋,設計方案找出n,並且保證在最壞情況下,最小化雞蛋下落的次數。假設每次摔落時,如果沒有摔碎,則不會給雞蛋帶來損耗 二 解題思路 我們先假設最壞情況下,雞蛋下落次數為x,即我們為了找出n...
2個雞蛋從100層摔(N個雞蛋從M樓層摔)
一 題目 有一棟樓共100層,乙個雞蛋從第n層及以上的樓層落下來會摔破,在第n層以下的樓層落下不會摔破。給你2個雞蛋,設計方案找出n,並且保證在最壞情況下,最小化雞蛋下落的次數。假設每次摔落時,如果沒有摔碎,則不會給雞蛋帶來損耗 二 解題思路 我們先假設最壞情況下,雞蛋下落次數為x,即我們為了找出n...
從 N 個元素中選取 M 個元素, 有多少種組合
演算法 從 n 個數字中選取 m 個,列印所有可能組合 使用乙個輔助陣列 aux 1.m 用來記錄 input 1.n 中被選中元素的索引 比如 input i 被選中,那麼中會有一項 aux i 從後向前計算 基本思想是,從 n 個元素中選取 m 個,首先選取第 m 個,然後在從剩下的選取 m 1...