You are given
K
eggs, and you have access to a building withN
floors from1
toN
.Each egg is identical in function, and if an egg breaks, you cannot drop it again.
You know that there exists a floor
F
with0 <= F <= N
such that any egg dropped at a floor higher thanF
will break, and any egg dropped at or below floorF
will not break.Each move, you may take an egg (if you have an unbroken one) and drop it from any floor
X
(with1 <= 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 ofF
?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
概述
求 [0~N] 升序列的极小最大查找次数。限定了鸡蛋数,如果查找后发现目标在二分点右侧(大于等于楼层),鸡蛋-1.
以下用一个从左到右的数轴代替拔地而起的楼层来说明,在n层扔鸡蛋相当于把序列分割为[0,n-1],[n~N]。
思路
我一开始想找出解析表达式,WA多次后反复推导模型,发现只有递推关系式...
这道题看似一道与二分相关的复杂贪心题,实际很容易找出dp解法。
首先需要想到的思路方向是,解法应当寻找给定K,F对应可搜索的楼层上界,而不是从K,N计算F,从K,N计算无规律可循。
然后想到K和F都会影响F上界。F增加,在鸡蛋没摔破时相当于K增加。
最后跟着DP的思路,发现在K个鸡蛋,限定F行动数的条件下扔鸡蛋后,要求在K,F-1条件下处理分割后的左数组;而右边的条件是K-1,F-1.
进一步易证,一组K,F对应的楼层上界,等于扔一个鸡蛋后左右两边余下K,F对应的楼层上界之和。
- 每一次行动中,除了扔鸡蛋外别无选择,而不论怎样,扔鸡蛋后被分割出的左右两段,它们的余下K,F是一定的。
这样我们就得到了一个递推关系式:dp[i][j] = dp[i-1][j-1] + dp[i][j-1],dp[i][0]=1,
其中i表示鸡蛋数K,j表示行动数F,以楼层上界为状态dp[i][j].
观察递推式中j非常乖巧,可对j迭代,一维dp实现。当dp[K]第一次大于等于N+1时输出j.(0~N共N+1个数)
由于K比N小得多,不用担心dp数组不必要地过大。
代码
class Solution {
public:
int superEggDrop(int K, int N) {
int dp[K+1];
for(int i=0;i<=K;i++)
dp[i]=1;
int r=0;
while(dp[K]<N+1){
for(int i=K;i>0;i--)
dp[i]+=dp[i-1];
r++;
}
return r;
}
};
http://www.cnblogs.com/hizcard/ 转载请注明出处