- Super Egg Drop
https://leetcode.com/problems/super-egg-drop/description/
Difficulty:Hard
Total Accepted:3.9K
Total Submissions:16.3K
You are given K eggs, and you have access to a building with N floors from 1 to N.
Each egg is identical in function, and if an egg breaks, you cannot drop it again.
You know that there exists a floor F with 0 <= F <= N such that any egg dropped at a floor higher than F will break, and any egg dropped at or below floor F will not break.
Each move, you may take an egg (if you have an unbroken one) and drop it from any floor X (with 1 <= X <= N).
Your goal is to know with certainty what the value of F is.
What is the minimum number of moves that you need to know with certainty what F is, regardless of the initial value of F?
Example 1:
Input: K = 1, N = 2
Output: 2
Explanation:
Drop the egg from floor 1. If it breaks, we know with certainty that F = 0.
Otherwise, drop the egg from floor 2. If it breaks, we know with certainty that F = 1.
If it didn't break, then we know with certainty F = 2.
Hence, we needed 2 moves in the worst case to know what F is with certainty.
Example 2:
Input: K = 2, N = 6
Output: 3
Example 3:
Input: K = 3, N = 14
Output: 4
Note:
1 <= K <= 100
1 <= N <= 10000
此题与其他的动态规划题咋一看不太一样,一开始以为只是一个二分查找,不断二分查找知道只剩最后一个蛋的时候在剩余的范围遍历,但显然这个不是最优解决思路,因为二分查找的时候数字不一定可以整除2,左右两边蛋碎和但没碎包含的节点数不一样,最终得到的最少步数结果表示的结果可能出错。
接下来考虑动态规划,划分状态的思路有两种:
- 一种是根据K和N来划分,多加一个节点,就从其余的N个节点求解得到的最差的最小步数加一。
dp[K][N] = 1 + max(dp[K - 1][i - 1],dp[K][N - i]) for i in 1...N.
- 另一种是根据最小步数m和K来求N,dp[m][k]表示m步和K个鸡蛋能够求解F的最大层数N
dp[m][k] = dp[m - 1][k] + dp[m - 1][k - 1] + 1; k=1....K
- 状态图
m步k个蛋可以求的楼层数
/(没碎) \(碎了一个蛋)
m-1步k个蛋可以求的楼层数 m-1步k-1个蛋可以求的楼层数
代码:
class Solution {
public:
int superEggDrop(int K, int N) {
vector<vector<int>> dp(N + 1, vector<int>(K + 1, 0));
int m = 0,k=0;
while (dp[m][K] < N) {
m++;
for (int k = 1; k <= K; k++) {
dp[m][k] = dp[m - 1][k] + dp[m - 1][k - 1] + 1;
}
}
return m;
}
};