887 雞蛋掉落

2022-06-07 13:48:13 字數 2424 閱讀 5038

方法1:動態規劃

最重要的是變換思想,從知道雞蛋數k,知道層數n,求最少次數m;轉化為知道雞蛋數k,假設最多只能扔m次,求最大能排除的層數。

建立乙個二維列表dp[k][n]來記錄最大能排除層數(m<=n,即使一層一層扔,最多也只會扔n次,保證不會溢位)。

dp[0][:]=0 : 0個雞蛋,無論扔多少次,只能排除0層數;

dp[:][0]=0 : 無論多少雞蛋,扔0次,只能排除0層數。

某一狀態,總共有k個雞蛋,最多扔m次,要找的那一層為第f層。因為dp記錄的是最大能排除的層數,所以我們扔的這一層,是最佳的。也就是,能排除f在樓上的情況:蛋沒碎,那麼還有k個雞蛋,可以扔m-1次;能排除f在樓下的情況:蛋碎了,那麼還有k-1個雞蛋,可以扔m-1次;能排除f就在當前樓。

dp[k][m] = dp[k][m-1]+dp[k-1][m-1]+1

知道了上面的轉移方程,我們可以用兩個迴圈,外迴圈是m一次一次增加,內迴圈是k乙個乙個增加。當某一迴圈中,扔k個雞蛋可以排除超過n層了,那麼說明,當前的m次就足夠了。

class solution:

def supereggdrop(self, k: int, n: int) -> int:

dp = [[0] * (k + 1) for _ in range(n + 1)]

for m in range(1, n + 1):

for k in range(1, k + 1):

dp[k][m] = dp[k][m-1] + dp[k - 1][m - 1] + 1

if dp[k][m] >= n:

return m

方法2.遞迴解法1.定義狀態f(k,n):有k個雞蛋和n層,f(k,n)代表找到臨界樓層需要的最小移動次數

2.雞蛋只有碎/不碎兩種情況。

3.將雞蛋扔在x層,若碎,則在[1...x-1]層找(共x-1層),雞蛋數-1;

4.若不碎,則在[x+1...n]層找(共n-x層)

5.我們需要找到最壞的一種情況,因此將雞蛋扔在x層時,找到臨界樓層需要的最小移動次數為fx(k,n) = max,x∈[1,n]

6.可知f(k,n)應該為所有情況中的最小值,即f(k,n) = min

class solution:

def supereggdrop(self, k: int, n: int) -> int:

def parse(k, n):

if n == 1: # 如果只有1層,不管有多少蛋只需試1次

return 1

elif n == 0:

return 0

elif k == 1: # 只有1個雞蛋,則只能逐層試

return n

elif (k, n) in table:

return table[(k, n)]

f = float('inf') # 定義乙個無限大數作為初始條件

for x in range(1, n + 1): # 將雞蛋扔在第x層,從第1層開始

fx = 1 + max(parse(k - 1, x - 1), parse(k, n - x))

f = min(f, fx)

table[(k, n)] = f

return f

table = {} # 記憶被計算過的情況

return parse(k, n)

時間複雜度:o(kn^2)

f = float('inf')  # 定義乙個無限大數作為初始條件

for x in range(1, n + 1): # 將雞蛋扔在第x層,從第1層開始

fx = 1 + max(parse(k - 1, x - 1), parse(k, n - x))

f = min(f, fx)

改為:

while lp <= rp:  

mid = lp + (rp-lp) // 2 # 二分法優化

bcase = parse(k-1, mid-1) # 蛋碎的情況

notbcase = parse(k,n-mid) # 不碎的情況

# fx = 1 + max(bcase, notbcase)

if bcase > notbcase:

rp = mid - 1

f = min(f, bcase + 1)

else:

lp = mid + 1

f = min(f,notbcase + 1)

時間複雜度:o(knlogn)

887 雞蛋掉落

你將獲得 k 個雞蛋,並可以使用一棟從 1 到 n 共有 n 層樓的建築。每個蛋的功能都是一樣的,如果乙個蛋碎了,你就不能再把它掉下去。你知道存在樓層 f 滿足 0 f n 任何從高於 f 的樓層落下的雞蛋都會碎,從 f 樓層或比它低的樓層落下的雞蛋都不會破。你的目標是確切地知道 f 的值是多少。無...

887 雞蛋掉落

你將獲得k個雞蛋,並可以使用一棟從1到n共有n層樓的建築。每個蛋的功能都是一樣的,如果乙個蛋碎了,你就不能再把它掉下去。你知道存在樓層f,滿足0 f n任何從高於f的樓層落下的雞蛋都會碎,從f樓層或比它低的樓層落下的雞蛋都不會破。你的目標是確切地知道f的值是多少。無論f的初始值如何,你確定f的值的最...

887 雞蛋掉落

你將獲得 k 個雞蛋,並可以使用一棟從 1 到 n 共有 n 層樓的建築。每個蛋的功能都是一樣的,如果乙個蛋碎了,你就不能再把它掉下去。你知道存在樓層 f 滿足 0 f n 任何從高於 f 的樓層落下的雞蛋都會碎,從 f 樓層或比它低的樓層落下的雞蛋都不會破。你的目標是確切地知道 f 的值是多少。無...