题目:
出处:
参考的解法:
class Solution {
public int superEggDrop(int K, int N) {
int[][] memo = new int[K + 1][N + 1];
return helper(K, N, memo);
}
private int helper(int K, int N, int[][] memo) {
if (N <= 1) {
return N;
}
if (K == 1) {
return N;
}
if (memo[K][N] > 0) {
return memo[K][N];
}
int low = 1, high = N, result = N;
while (low < high) {
int mid = low + (high - low) / 2;
int left = helper(K - 1, mid - 1, memo);
int right = helper(K, N - mid, memo);
result = Math.min(result, Math.max(left, right) + 1);
if (left == right) {
break;
} else if (left < right) {
low = mid + 1;
} else {
high = mid;
}
}
memo[K][N] = result;
return result;
}
}
相较于大神的代码,自己的思路是设置一个存储数组,f[K][N] = 1+max(f[K-1][m-1],f[K][N-m);m从1到N遍历,这样的结果就是时间超时。上面的代码,我们可以看出最小的次数是,m点的左右两边的阶数基本一致,从而使得两边检查的次数大约一样,这样总和就最小了。在while循环中不断猜测m的位置,并记录最小的次数。如果遇到理想情况,即左边的次数等于右边的次数,则直接返回,否则当low>high,我们将遇到的最小次数返回就可以了。