Classic DP: Super Egg(Advanced Solution)
Translator: Jieyixia
Author: labuladong
The Super Egg Drop problem (Leetcode 887) has been discussed in the last article using the classic dynamic programming method. If you are not very familiar with this problem and the classic method, please read「Super Egg Drop」, which is the basic of following contents.
In this article, we will optimize this problem with other two more efficient methods. One is adding binary search into the classic dynamic programming method, the other one is redefining state transition equation.
Binary Search Optimization
We want to find the floor F
for a building with N
floors using minimum number of moves (Each move means dropping an egg from a certain floor). Any egg dropped at a floor higher than F
will break, and any egg dropped at or below floor F
will not break. First, let's review the classic dynamic programming method:
1、To know F
, we should traverse the situations that we drop an egg from floor i
, 1 <= i <= N
and find the situation that costs minimum number of moves;
2、Anytime we drop an egg, there are two possible outcomes: the egg is broken or not broken;
3、If the egg is broken, F
<= i
; else, F
> i
;
Whether the egg is broken or not depends on which outcome causes more moves, since the goal is to know with certainty what the value of
F
is, regardless of its initial value.
The code for state transition:
The above code reflects the following state transition equation:
If you can understand the state transition equation, it is not difficult to understand how to use binary search to optimize the process.
From the definition of dp(K, N)
array (the minimum number of moves with K
eggs and N
floors), we know that when K
is fixed, dp(K, N)
will increase monotonically as N
increases. In the above state transition equation, dp(K - 1, i - 1)
will increase monotonically and dp(K, N - i)
will decrease monotonically as i
increases from 1 to N
.
We need to find the maximum between dp(K - 1, i - 1)
and dp(K, N - i)
, and then choose the minimum one among those maximum values. This means that we should get the intersection of the two straight lines (the lowest points of the red polyline).
In other article, we have mentioned that binary search is widely used in many cases, for example:
In the above case, it is likely to use binary search to optimize the complexity of linear search. Review the two dp
functions, the lowest point satisfies following condition:
If you are familiar with binary search, it is easy to know that what we need to search is the valley value. Let's look at the following code:
The time complexity for dynamic programming problems is the number of sub-problems × the complexity of function.
Regardless of the recursive part, the complexity of dp
function is O(logN), since binary search is used.
The number of sub-problems equals to the number of different states, which is O(KN).
Therefore, the time complexity of the improved method is O(K*N*logN), which is more efficient than O(KN^2) of the classic dynamic programming method. The space complexity is O(KN).
Redefine State Transition Equation
It has been mentioned in other article that the state transition equation for the same problem is not unique, resulting in different methods with different complexity.
Review the definition of the dp
function:
Or the dp
array:
Based on this definition, the expected answer is dp(K, N)
. The method of exhaustion is necessary, we have to compare the results under different situations 1<=i<=N
to find the minimum. Binary search helps to reduce the search space.
Now, we make some modifications to the definition of dp
array, current states are k
eggs and allowed maximum number of moves m
. dp[k][m] = n
represents that we can accurately determine a floor F
for a building with at most n
floors. More specifically:
This is actually a reverse version of our original definition. We want to know the number of moves at last. But under this new definition, it is one state of the dp
array instead of the result. This is how we deal with this problem:
The while
loop ends when dp[K][m] == N
, which means that given K
eggs and at most m
moves, floor F
can be accurately determined for a building with N
floors. This is exactly the same as before.
Then how to find the state transition equation? Let's start from the initial idea:
You have to traverse 1<=i<=N
to find the minimum. But these are not necessary under the new definition of dp
array. This is based on the following two facts:
1、There are only two possible outcomes when you drop an egg at any floor: the egg is broken or not broken. If the egg is broken, go downstairs. If the egg is not broken, go upstairs。
2、No matter which outcome, total number of floors = the number of floors upstairs + the number of floors downstairs + 1(current floor)。
Base on the two facts, we can write the following state transition equation:
dp[k][m] = dp[k][m - 1] + dp[k - 1][m - 1] + 1
dp[k][m - 1]
is the number of floors upstairs. k
keeps unchanged since the egg is not broken, m
minus one;
dp[k - 1][m - 1]
is the number of floors downstairs. k
minus one since the egg is broken, m
minus one.
PS: why m
minus one instead of plus one? According to the definition, m
is the upper bound of the number of moves, instead of the number of moves。
The code is:
which equals to:
It seems more familiar. Since we need to get a certain index m
of the dp
array, while
loop is used.
The time complexity of this algorithm is apparently O(KN), two nested for
loop。
Moreover, dp[m][k]
only relates to the left and left-top states, it is easy to simplify dp
array to one dimension.
More Optimization
In this section, we will introduce some mathematical methods without specific details.
Based on the dp
definition in the previous section, dp(k, m)
increases monotonically when m
increases. When k
is fixed, a bigger m
will cause a bigger N
。
We can also use binary search to optimize the process, dp[K][m] == N
is the stop criterion. Time complexity further decreases to O(KlogN), we can assume g(k, m) =
……
All right, let's stop. I think it's enough to understand the binary search method with O(K*N*logN) time complexity.
It is certain that we should change the for loop to find m
:
In conclusion, the first optimization using binary search is based on the monotonicity of the dp
function; the second optimization modifies the state transition function. For most of us, it is easier to understand the idea of binary search instead of different forms of dp
array.
If you have grasped the basic methods well, the methods in the last section are good challenges for you.
Last updated