28
28
29
29
## 解题思路
30
30
31
- ### 思路 1:动态规划(超时)
32
-
33
- 这道题目的题意不是很容易理解,我们先把题目简化一下,忽略一些限制条件,理解简单情况下的题意。然后再一步步增加限制条件,从而先弄明白这道题目的意思。
31
+ 这道题目的题意不是很容易理解,我们先把题目简化一下,忽略一些限制条件,理解简单情况下的题意。然后再一步步增加限制条件,从而弄明白这道题目的意思。以及思考解题思路。
34
32
35
33
我们先忽略 ` k ` 个鸡蛋这个条件,假设有无限个鸡蛋。
36
34
43
41
- 如果鸡蛋没摔碎,则可以继续选择其他楼层进行测试。
44
42
- 如果鸡蛋摔碎了,则该鸡蛋无法继续测试。
45
43
46
- 现在题目要求:一共有 ` n ` 层楼,无限个鸡蛋,求出至少需要扔几次鸡蛋,才能保证无论 ` f ` 是多少层,都能将 ` f ` 找出来?
44
+ 现在题目要求:** 已知有 ` n ` 层楼,无限个鸡蛋,求出至少需要扔几次鸡蛋,才能保证无论 ` f ` 是多少层,都能将 ` f ` 找出来?**
47
45
48
46
最简单且直观的想法:
49
47
61
59
- 如果鸡蛋碎了,则从第 ` 1 ` 层到中间层这个区间中去扔鸡蛋。
62
60
- 如果鸡蛋没碎,则从中间层到第 ` n ` 层这个区间中去扔鸡蛋。
63
61
64
- 每次扔鸡蛋都从区间的中间层去扔,这样每次都能排除当前区间一半的答案,从而最终确定鸡蛋不会摔碎的最高楼层 ` f ` 。。
62
+ 每次扔鸡蛋都从区间的中间层去扔,这样每次都能排除当前区间一半的答案,从而最终确定鸡蛋不会摔碎的最高楼层 ` f ` 。
65
63
66
64
通过这种二分查找的方法,可以优化到 $\log n$ 次就能确定鸡蛋不贵摔碎的最高楼层 ` f ` 。
67
65
71
69
72
70
这是不限制鸡蛋个数的情况下,现在在给定 ` n ` 层楼的基础上,再限制一下鸡蛋个数为 ` k ` 。
73
71
74
- 现在题目要求:一共有 ` n ` 层楼,` k ` 个鸡蛋,求出至少需要扔几次鸡蛋,才能保证无论 ` f ` 是多少层,都能将 ` f ` 找出来?
72
+ 现在题目要求:** 已知有 ` n ` 层楼,` k ` 个鸡蛋,求出至少需要扔几次鸡蛋,才能保证无论 ` f ` 是多少层,都能将 ` f ` 找出来?**
75
73
76
74
如果鸡蛋足够多(大于等于 $\log_2 n$ 个),可以通过二分查找的方法来测试。如果鸡蛋不够多,可能二分查找过程中,鸡蛋就用没了,则不能通过二分查找的方法来测试。
77
75
78
- 那么这时候为了找出 ` f ` ,我们应该如何求出最少的扔鸡蛋次数。
76
+ 那么这时候为了找出 ` f ` ,我们应该如何求出最少的扔鸡蛋次数?
77
+
78
+ ### 思路 1:动态规划(超时)
79
79
80
80
可以这样考虑。题目限定了 ` n ` 层楼,` k ` 个鸡蛋。
81
81
@@ -146,7 +146,7 @@ class Solution:
146
146
147
147
### 思路 2:动态规划优化
148
148
149
- 上一步中时间复杂度为 $O(n^2 \times k)$。根据 $n$ 的规模,提交上去补出意外的超时了 。
149
+ 上一步中时间复杂度为 $O(n^2 \times k)$。根据 $n$ 的规模,提交上去不出意外的超时了 。
150
150
151
151
我们可以观察一下上面的状态转移方程 $dp[ i] [ j ] = min_ {1 \le x \le n} (max(dp[ i - x] [ j ] , dp[ x - 1] [ j - 1 ] )) + 1$ 。
152
152
@@ -197,21 +197,55 @@ class Solution:
197
197
198
198
### 思路 3:动态规划 + 逆向思维
199
199
200
+ 再看一下我们现在的题目要求:已知有 ` n ` 层楼,` k ` 个鸡蛋,求出至少需要扔几次鸡蛋,才能保证无论 ` f ` 是多少层,都能将 ` f ` 找出来?
201
+
202
+ 我们可以逆向转换一下思维,将题目转变为:** 已知有 ` k ` 个鸡蛋,最多扔 ` x ` 次鸡蛋(碎没碎都算 ` 1 ` 次),求最多可以检测的多少层?**
203
+
204
+ 我们把未知条件「扔鸡蛋的次数」变为了已知条件,将「检测的楼层个数」变为了未知条件。
205
+
206
+ 这样如果求出来的「检测的楼层个数」大于等于 ` n ` ,则说明 ` 1 ` ~ ` n ` 层楼都考虑全了,` f ` 值也就明确了。我们只需要从符合条件的情况中,找出「扔鸡蛋次数」最少的次数即可。
207
+
208
+ 动态规划的具体步骤如下:
209
+
210
+ ###### 1. 划分阶段
211
+
212
+ 按照鸡蛋个数、扔鸡蛋的次数进行阶段划分。
213
+
214
+ ###### 2. 定义状态
215
+
216
+ 定义状态 ` dp[i][j] ` 表示为:一共有 ` i ` 个鸡蛋,最多扔 ` j ` 次鸡蛋(碎没碎都算 ` 1 ` 次)的条件下,最多可以检测的楼层个数。
217
+
218
+ ###### 3. 状态转移方程
219
+
220
+ 我们现在有 ` i ` 个鸡蛋,` j ` 次扔鸡蛋的机会,现在尝试在 ` 1 ` ~ ` n ` 层中的任意一层 ` x ` 扔鸡蛋:
200
221
222
+ 1 . 如果鸡蛋没碎,剩下 ` i ` 个鸡蛋,还有 ` j - 1 ` 次扔鸡蛋的机会,最多可以检测 ` dp[i][j - 1] ` 层楼层。
223
+ 2 . 如果鸡蛋碎了,剩下 ` i - 1 ` 个鸡蛋,还有 ` j - 1 ` 次扔鸡蛋的机会,最多可以检测 ` dp[i - 1][j - 1] ` 层楼层。
224
+ 3 . 再加上我们扔鸡蛋的第 ` x ` 层,` i ` 个鸡蛋,` j ` 次扔鸡蛋的机会最多可以检测 ` dp[i][j - 1] + dp[i - 1][j - 1] + 1 ` 层。
225
+
226
+ 则状态转移方程为:$dp[ i] [ j ] = dp[ i] [ j - 1 ] + dp[ i - 1] [ j - 1 ] + 1$。
227
+
228
+ ###### 4. 初始条件
229
+
230
+ - 当鸡蛋数为 ` 1 ` 时,只有 ` 1 ` 次扔鸡蛋的机会时,最多可以检测 ` 1 ` 层,即 ` dp[1][1] = 1 ` 。
231
+
232
+ ###### 5. 最终结果
233
+
234
+ 根据我们之前定义的状态,` dp[i][j] ` 表示为:一共有 ` i ` 个鸡蛋,最多扔 ` j ` 次鸡蛋(碎没碎都算 ` 1 ` 次)的条件下,最多可以检测的楼层个数。则我们需要从满足 ` i == k ` 并且 ` dp[i][j] >= n ` (即 ` k ` 个鸡蛋,` j ` 次扔鸡蛋,一共检测出 ` n ` 层楼)的情况中,找出最小的 ` j ` ,将其返回。
201
235
202
236
### 思路 3:代码
203
237
204
238
``` Python
205
239
class Solution :
206
240
def superEggDrop (self , k : int , n : int ) -> int :
207
- dp = [[i for _ in range (k + 1 )] for i in range (n + 1 )]
241
+ dp = [[0 for _ in range (n + 1 )] for i in range (k + 1 )]
208
242
dp[1 ][1 ] = 1
209
243
210
- for i in range (1 , n + 1 ):
211
- for j in range (1 , k + 1 ):
212
- dp[i][j] = dp[i - 1 ][j ] + dp[i - 1 ][j - 1 ] + 1
213
- if j == k and dp[i][j] >= n:
214
- return i
244
+ for i in range (1 , k + 1 ):
245
+ for j in range (1 , n + 1 ):
246
+ dp[i][j] = dp[i][j - 1 ] + dp[i - 1 ][j - 1 ] + 1
247
+ if i == k and dp[i][j] >= n:
248
+ return j
215
249
return n
216
250
```
217
251
@@ -224,3 +258,4 @@ class Solution:
224
258
225
259
- 【题解】[ 题目理解 + 基本解法 + 进阶解法 - 鸡蛋掉落 - 力扣] ( https://leetcode.cn/problems/super-egg-drop/solution/ji-ben-dong-tai-gui-hua-jie-fa-by-labuladong/ )
226
260
- 【题解】[ 动态规划(只解释官方题解方法一)(Java) - 鸡蛋掉落 - 力扣] ( https://leetcode.cn/problems/super-egg-drop/solution/dong-tai-gui-hua-zhi-jie-shi-guan-fang-ti-jie-fang/ )
261
+ - 【题解】[ 动态规划 & 记忆化搜索 2000ms -> 32ms 的过程 - 鸡蛋掉落 - 力扣] ( https://leetcode.cn/problems/super-egg-drop/solution/python-dong-tai-gui-hua-ji-yi-hua-sou-su-hnj9/ )
0 commit comments