大樓扔雞蛋問題 dp poj 3783

2021-07-09 02:20:17 字數 1279 閱讀 9008

題意分析:

經典題,小白書上的一道例題,4+2出了這道原題,我愣是以為是數學題,最後也沒做出來。題意是這樣的,給你n個雞蛋(硬度一樣),讓你測雞蛋的硬度,測量的方法就是從某棟m層的樓的某一層x上把雞蛋扔下來,如果雞蛋碎了,代表他的強度小於x;如果沒碎,則強度大於等於x。我們要做的就是不斷的從樓上把雞蛋扔下來,直到找到某一層樓x,從這一層樓扔下來雞蛋不碎掉,從x+1層扔下來雞蛋碎掉,那麼雞蛋的強度就是x。如果在m層扔下來雞蛋也不碎掉,那麼雞蛋的強度為m。問題是,用n個雞蛋最多需要幾步可以把硬度測出來(雞蛋碎掉就不能用了,而且必須測出來!)。

解題思路:

一開始看懂題意之後,我馬上就想到了二分法,但是仔細一想並不對,如果雞蛋的數量足夠的話,二分法絕對是最快的,但是如果雞蛋不夠,就不太一樣了。如果第一次扔就碎了乙個雞蛋,那麼剩下的雞蛋就只能從下往上測試,這樣2個雞蛋、100層樓的情況最多可能需要51步,然而測試樣例告訴我們,只要14步,當時想了足足有半個鐘才想到他可以用這樣的步長進行測試,這樣最多的測試數都是14次,這樣的原則確確實實可以解決2個雞蛋的問題,但是3個雞蛋就跪了,於是有了動態規劃演算法。 

動態規劃演算法:

狀態:dp[i][j]表示n=i,m=j時,最多需要多少次測試。 

狀態轉移方程:

如果我們一開始是在k層進行測試的,那麼如果雞蛋破碎了,我們的查詢範圍就變成k層一下的k-1層,當然此時雞蛋數減少了,所以最終的步數應該為dp[i-1][k-1]+1;另外一種情況是雞蛋沒有碎的情況,我們要找的範圍變成了k層以上的,所以最終需要dp[i][j-k]+1步。我們的目標就是要找到乙個k,使得最壞情況下測試數最少,所以我們需要列舉k。

#include #include #include #include #include #include #include using namespace std;

#define inf 0x3f3f3f3f

int dp[55][1005];

int n,m,c;

void cal()

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

for(int i = 2 ; i < 55 ; i++)}}

}int main()

return 0;

}

ps:這個題目很典型也很經典,各種版本的都有,但基本的意思是一樣的。

但是這個題目變形之後的一種是,樓層非常高達到2000000007,另外假如32次還不能確定最終的答案的話就直接輸出不可能。

這樣我就有點不確定怎麼寫了,應該要做個初始化嗎,還是怎麼樣,直接dp肯定是不行的。求大神幫忙。

再談大樓扔雞蛋的問題

這道題是說,100層樓,兩個一模一樣的雞蛋,某層之上扔雞蛋就會碎。問要測試多少次才能找出這層樓來。我曾經在去年初的這篇文章裡面討論過這個問題的解法,因為只想記錄一下思路和討論過程,寫得很簡略。現在,我想重新整理一下這個問題,再稍稍擴充套件和挖掘一下。希望可以用盡可能清晰易懂的描述,把這個問題的前後說...

扔雞蛋問題

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

扔雞蛋問題

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