Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cbfc537

Browse files
Update 887.super-egg-drop.md
1 parent 46b22c5 commit cbfc537

File tree

1 file changed

+102
-44
lines changed

1 file changed

+102
-44
lines changed

‎problems/887.super-egg-drop.md

Lines changed: 102 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 题目地址(887. 鸡蛋掉落)
22

3-
原题地址:https://leetcode-cn.com/problems/super-egg-drop/
3+
https://leetcode-cn.com/problems/super-egg-drop/
44

55
## 题目描述
66

@@ -197,81 +197,139 @@ class Solution:
197197

198198
我们只需要返回第一个返回值为 true 的 m 即可。
199199

200-
> 想到这里,我条件发射地想到了二分法。 聪明的小朋友们,你们觉得二分可以么?为什么?欢迎评论区留言讨论
200+
对于这种二段性的题目应该想到二分法,如果你没想起来,请先观看我的仓库里的二分专题哦。实际上不二分也完全可以通过此题目,具体参考下方代码区,有实现带二分的和不带二分的
201201

202-
那么这个神奇的 f 函数怎么实现呢?其实很简单。
202+
最后剩下一个问题。这个神奇的 f 函数怎么实现呢?其实很简单。
203203

204204
- 摔碎的情况,可以检测的最高楼层是`f(m - 1, k - 1) + 1`。因为碎了嘛,我们多检测了摔碎的这一层。
205205
- 没有摔碎的情况,可以检测的最高楼层是`f(m - 1, k)`。因为没有碎,也就是说我们啥都没检测出来(对能检测的最高楼层无贡献)。
206206

207-
我们来看下代码:
207+
能检测的最高楼层就是两者的和,我们来看下代码:
208208

209209
```py
210210
class Solution:
211211
def superEggDrop(self, K: int, N: int) -> int:
212+
213+
@cache
212214
def f(m, k):
213215
if k == 0 or m == 0: return 0
214216
return f(m - 1, k - 1) + 1 + f(m - 1, k)
215-
m = 0
216-
while f(m, K) < N:
217-
m += 1
218-
return m
217+
l, r = 1, N
218+
while l <= r:
219+
mid = (l + r) // 2
220+
if f(mid, K) >= N:
221+
r = mid - 1
222+
else:
223+
l = mid + 1
224+
225+
return l
219226
```
220227

221-
上面的代码可以 AC。我们来顺手优化成迭代式。
228+
## 代码
229+
230+
代码支持:Python, CPP, Java, JavaSCript
231+
232+
Python:
222233

223234
```py
224235
class Solution:
225236
def superEggDrop(self, K: int, N: int) -> int:
226-
dp = [[0] * (K + 1) for _ in range(N + 1)]
227-
m = 0
228-
while dp[m][K] < N:
229-
m += 1
230-
for i in range(1, K + 1):
231-
dp[m][i] = dp[m - 1][i - 1] + 1 + dp[m - 1][i]
232-
return m
237+
238+
@cache
239+
def f(m, k):
240+
if k == 0 or m == 0: return 0
241+
return f(m - 1, k - 1) + 1 + f(m - 1, k)
242+
l, r = 1, N
243+
while l <= r:
244+
mid = (l + r) // 2
245+
if f(mid, K) >= N:
246+
r = mid - 1
247+
else:
248+
l = mid + 1
249+
250+
return l
233251
```
234252

235-
## 代码
253+
CPP:
254+
255+
```cpp
256+
#include <vector>
257+
#include <functional>
258+
259+
class Solution {
260+
public:
261+
int superEggDrop(int K, int N) {
262+
std::vector<std::vector<int>> dp(K + 1, std::vector<int>(N + 1, 0));
263+
264+
for (int m = 1; m <= N; ++m) {
265+
for (int k = 1; k <= K; ++k) {
266+
dp[k][m] = dp[k - 1][m - 1] + 1 + dp[k][m - 1];
267+
if (dp[k][m] >= N) {
268+
return m;
269+
}
270+
}
271+
}
272+
273+
return N; // Fallback, should not reach here
274+
}
275+
};
236276

237-
代码支持:JavaSCript,Python
277+
```
238278
239-
Python:
279+
Java:
280+
281+
```java
282+
import java.util.Arrays;
283+
284+
class Solution {
285+
public int superEggDrop(int K, int N) {
286+
int[][] dp = new int[K + 1][N + 1];
287+
288+
for (int m = 1; m <= N; ++m) {
289+
for (int k = 1; k <= K; ++k) {
290+
dp[k][m] = dp[k - 1][m - 1] + 1 + dp[k][m - 1];
291+
if (dp[k][m] >= N) {
292+
return m;
293+
}
294+
}
295+
}
296+
297+
return N; // Fallback, should not reach here
298+
}
299+
}
240300
241-
```py
242-
class Solution:
243-
def superEggDrop(self, K: int, N: int) -> int:
244-
dp = [[0] * (K + 1) for _ in range(N + 1)]
245-
m = 0
246-
while dp[m][K] < N:
247-
m += 1
248-
for i in range(1, K + 1):
249-
dp[m][i] = dp[m - 1][i - 1] + 1 + dp[m - 1][i]
250-
return m
251301
```
252302

253303
JavaSCript:
254304

255305
```js
256-
var superEggDrop = function (K, N) {
257-
// 不选择dp[K][M]的原因是dp[M][K]可以简化操作
258-
const dp = Array(N + 1)
259-
.fill(0)
260-
.map((_) => Array(K + 1).fill(0));
261-
262-
let m = 0;
263-
while (dp[m][K] < N) {
264-
m++;
265-
for (let k = 1; k <= K; ++k) dp[m][k] = dp[m - 1][k - 1] + 1 + dp[m - 1][k];
266-
}
267-
return m;
268-
};
306+
/**
307+
* @param {number} k
308+
* @param {number} n
309+
* @return {number}
310+
*/
311+
var superEggDrop = function superEggDrop(K, N) {
312+
const dp = Array.from({ length: K + 1 }, () => Array(N + 1).fill(0));
313+
314+
for (let m = 1; m <= N; ++m) {
315+
for (let k = 1; k <= K; ++k) {
316+
dp[k][m] = dp[k - 1][m - 1] + 1 + dp[k][m - 1];
317+
if (dp[k][m] >= N) {
318+
return m;
319+
}
320+
}
321+
}
322+
323+
return N; // Fallback, should not reach here
324+
}
325+
326+
269327
```
270328

271329
**复杂度分析**
272330

273-
- 时间复杂度:$O(m * K),ドル其中 m 为答案。
274-
- 空间复杂度:$O(K * N)$
331+
- 时间复杂度:$O(m * K * logN)$
332+
- 空间复杂度:$O(m * K)$
275333

276334
对为什么用加法的同学有疑问的可以看我写的[《对《丢鸡蛋问题》的一点补充》](https://lucifer.ren/blog/2020/08/30/887.super-egg-drop-extension/)
277335

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /