你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

    你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

    每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

    你的目标是确切地知道 F 的值是多少。

    无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?


    1. public static int superEggDrop(int K, int N) {
    2. if( N == 0 || N == 1 || K ==1){
    3. return N;
    4. }
    5. int minimun = N;
    6. for(int i = 1; i <= N; i++){ // 依次遍历从第1层到第N层开始扔第1个鸡蛋的情况
    7. int tMin = Math.max(superEggDrop(K-1, i-1), superEggDrop(K, N-i));
    8. minimun = Math.min(minimun, 1 + tMin);
    9. }
    10. return minimun;
    11. }
    12. // 以上是最简单的解法,改进的办法是加入中间表,减少重复的节点计算, 如下所示:
    13. class Solution {
    14. public int superEggDrop(int K, int N) {
    15. int[][] middleResults = new int[K + 1][N + 1];
    16. for (int i = 1; i <= N; i++) {
    17. middleResults[1][i] = i; // only one egg
    18. middleResults[0][i] = 0; // no egg
    19. }
    20. for (int i = 1; i <= K; i++) {
    21. middleResults[i][0] = 0; // zero floor
    22. }
    23. for (int k = 2; k <= K; k++) { // start from two egg
    24. for (int n = 1; n <= N; n++) {
    25. int tMinDrop = N * N;
    26. for (int x = 1; x <= n; x++) {
    27. tMinDrop = Math.min(tMinDrop, 1 + Math.max(middleResults[k - 1][x - 1], middleResults[k][n - x]));
    28. }
    29. middleResults[k][n] = tMinDrop;
    30. }
    31. }
    32. return middleResults[K][N];
    33. }
    34. }