每日一道演算法題 高樓扔雞蛋問題 動態規劃問題

2021-09-29 17:30:09 字數 1642 閱讀 3611

題目是這樣:你面前有一棟從 1 到n共n層的樓,然後給你k個雞蛋(k至少為 1)。現在確定這棟樓存在樓層0 <= f <= n,在這層樓將雞蛋扔下去,雞蛋恰好沒摔碎(高於f的樓層都會碎,低於f的樓層都不會碎)。現在問你,最壞情況下,你至少要扔幾次雞蛋,才能確定這個樓層f呢?

首先我們來看一下,什麼叫做最壞情況下,至少要仍幾次雞蛋,才能確定這個樓層f?

我們來舉個簡單的例子,當雞蛋為1個時,如何確定這個樓層f,這時只能從第一層開始向上嘗試,當第一層沒有碎時,就繼續在第二層嘗試,。。。。。。,當在第k層嘗試時,雞蛋碎了(那麼說明n-1層已經嘗試過了且沒有碎),所以說我們需要扔k次才能確定樓層。但這個k最壞情況下是多少尼?肯定是一直扔到最高層才碎,此時k=n吧。

那麼當有k個雞蛋,n層樓時該如何做尼?

我們先來分析一下可不可以用動態規劃來解決。

1、找dp含義

dp[k][i]表示當有k個雞蛋,i層樓時,最壞情況下需要扔雞蛋的次數才能確定樓層f

2、找轉移狀態當在第i層樓扔雞蛋時,有兩種結果(碎了或沒碎)。

當沒碎的話,我們有k個雞蛋,但此時,我們需要從i+1 - n層繼續嘗試,找到樓層f,那麼此時的問題是你面前有一棟n-i層的樓,然後給你k個雞蛋(k至少為 1)。現在確定這棟樓存在樓層0 <= f <= n,在這層樓將雞蛋扔下去,雞蛋恰好沒摔碎(高於f的樓層都會碎,低於f的樓層都不會碎)。現在問你,最壞情況下,你至少要扔幾次雞蛋,才能確定這個樓層f呢?**

此時,轉移狀態就為 dp[k][i]=max(dp[k][n-i],dp[k-1][i-1])+1 //最壞情況下,子問題嘗試的次數還要加上本次嘗試的一次。

3、找結束條件

當i=0時,也就是樓層沒有高度,此時我們也就不用嘗試了,直接返回0;

當k=1時,也就是我們有1個雞蛋,那我們就只能從第一層開始嘗試,最壞情況下需要嘗試到頂層,也就是返回樓層的高度i;

有了轉移方程和結束條件,那麼**就可以寫出來了。

#include

#include

using

namespace std;

int memo[

500]

[500]=

;intdp(

int k,

int n)

return ans;

}int

main()

非遞迴實現

#include

#include

using

namespace std;

int dp[

500]

[500]=

;int

fun(

int k,

int n)

for(

int i =

1; i <= n; i++

)for

(int i =

2; i <= k; i++)}

dp[i]

[j]= res;}}

return dp[k]

[n];

}int

main()

每日一題 高樓扔雞蛋

2020.04.11 這題其實正常思路還可以,有點類似b站李永樂老師講的方法。核心還是尋找子問題,dp i j 表示一共有i層j個雞蛋。可以把dp i j 分為先在第m層扔一次,在剩下的結果裡繼續分析。dp i j min dp i j max dp m j 1 dp n m j 第乙個min對應最...

每日一道演算法題

no.1 設指標變數fron t表示鏈式佇列的隊頭指標,指標變數rear表示鏈式佇列的隊尾指標,指標變數s指向將要入佇列的結點x,則入佇列的操作序列為 a.front next s front s b.s next rear rear s crear next s rear s d.s next f...

每日一道演算法題

no.1 若有 18 個元素的有序表存放在一維陣列 a 19 中,第乙個元素放 a 1 中,現進行二分查詢,則查詢 a 3 的比較序列的下標依次為 a.1,2,3 b.9,5,2,3 c.9,5,3 d.9,4,2,3 答案 d.第一次查詢,隊首為下標1,隊尾下標18,所以是 1 18 2 9 第二...