你將獲得 k 個雞蛋,並可以使用一棟從 1 到 n 共有 n 層樓的建築。
每個蛋的功能都是一樣的,如果乙個蛋碎了,你就不能再把它掉下去。
你知道存在樓層 f ,滿足 0 <= f <= n 任何從高於 f 的樓層落下的雞蛋都會碎,從 f 樓層或比它低的樓層落下的雞蛋都不會破。
你的目標是確切地知道 f 的值是多少。
無論 f 的初始值如何,你確定 f 的值的最小移動次數是多少?
示例 1:
輸入:k = 1, n = 2
輸出:2
解釋:雞蛋從 1 樓掉落。如果它碎了,我們肯定知道 f = 0 。
否則,雞蛋從 2 樓掉落。如果它碎了,我們肯定知道 f = 1 。
如果它沒碎,那麼我們肯定知道 f = 2 。
因此,在最壞的情況下我們需要移動 2 次以確定 f 是多少。
示例 2:
輸入:k = 2, n = 6
輸出:3
示例 3:
輸入:k = 3, n = 14
輸出:4
1 <= k <= 100
1 <= n <= 10000
這是一道困難的題目,推薦基礎了解李永樂老師講解的雙蛋問題。
思路來說,leetcode官方題解中的第三種解法反而最容易懂,所以本文就講述一下我搞懂了的第三種方法。
已知
本題要求解的是n層樓使用k個雞蛋,至少扔m次能找到臨街樓層f。
又可解讀為
用k個雞蛋,操作t次,能找到最高的樓層是多少?需要滿足最高樓層》=n。所以需要找出最小能滿足f(t,k)>=n的t值
遞迴(動態規劃)思考過程
關於f(t,k)怎麼求,我們思考一下扔出乙個雞蛋,看看到底發生了什麼:
如果雞蛋沒有碎,那麼對應的是 f(t - 1, k),也就是說在這一層的上方可以有 f(t - 1, k) 層;
如果雞蛋碎了,那麼對應的是 f(t - 1, k - 1),也就是說在這一層的下方可以有 f(t - 1, k - 1)層。
因此我們就可以寫出狀態轉移方程:
f(t, k)
= 1 + f(t-1, k-1) + f(t-1, k)
邊界條件為:當 t≥1 的時候 f(t, 1) = t,當 k≥1 時,f(1,k)=1。
那麼t 最大可以達到多少?由於操作次數是一定不會超過樓層數的,因此 t≤n,我們只要算出在 f(n, k)內的所有 f 值即可。
基礎**
func
supereggdrop
(k int
, n int
)int
var f [
]int
for i:=
0;i<=n;i++
for i:=
1;i<=k;i++
ans :=-1
for i:=
2;i<=n;i++
if f[i]
[k]>=n
}return ans
}
高階優化**
func
supereggdrop
(k int
, n int
)int
times ++
}return times
}func
gettimes
(times, eggcount int
)int
return
gettimes
(times -
1, eggcount -1)
+1+gettimes
(times -
1, eggcount)
}
程式設計思想之遞迴
我之前寫過關於遞迴演算法 的博文,但作為程式設計思想系列的文章不得不再對它進行進一步深入的剖析。因為它是一種簡單 常用又重要的一種程式設計思想。舉乙個通俗的例子 有乙個8倆重的蘋果要你切成重量相等的若干份,每乙份的重量不能大於1倆。你肯定會想到這樣做 1.第一刀先把乙個蘋果切成重量均等的2份a1和a...
遞迴思想之 階乘演算法
關於階乘這裡簡單說明一下 階乘是什麼?1 x 2 x 3 x 4 x 5 5 這裡的5 就稱為5的階乘,之所以稱為階乘是因為乘數呈階梯狀遞減而得名,如下 5 5 x 4 x 3 x 2 x 1 1204 4 x 3 x 2 x 1 24 3 3 x 2 x 1 6 2 2 x 1 2 1 1 1 0...
遞迴思想解決小熊掰玉公尺問題。
小熊掰玉公尺 一天小熊來到一片玉公尺地,興奮的掰了若干個玉公尺,他發現太多了,於是扔了其中一半,感覺還是有點多,於是又扔了乙個後往家趕 當它走了一公尺的時候感覺有點累,於是扔掉其中的一半加乙個,繼續往前每走一公尺重複以往的動作,扔掉其中的一半加乙個 當它走到10公尺時候,發現手中就剩乙個了,有點傷感...