方法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:方法2.遞迴解法1.定義狀態f(k,n):有k個雞蛋和n層,f(k,n)代表找到臨界樓層需要的最小移動次數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.雞蛋只有碎/不碎兩種情況。
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:時間複雜度:o(kn^2)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)
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:時間複雜度:o(knlogn)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)
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 的值是多少。無...