雞蛋掉落
阿新 • • 發佈:2021-10-24
給你 k 枚相同的雞蛋,並可以使用一棟從第 1 層到第 n 層共有 n 層樓的建築。
已知存在樓層 f ,滿足0 <= f <= n ,任何從 高於 f 的樓層落下的雞蛋都會碎,從 f 樓層或比它低的樓層落下的雞蛋都不會破。
每次操作,你可以取一枚沒有碎的雞蛋並把它從任一樓層 x 扔下(滿足1 <= x <= n)。如果雞蛋碎了,你就不能再次使用它。如果某枚雞蛋扔下後沒有摔碎,則可以在之後的操作中 重複使用 這枚雞蛋。
請你計算並返回要確定 f 確切的值 的 最小操作次數 是多少?
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/super-egg-drop
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
心之所向,素履以往 生如逆旅,一葦以航import java.util.Scanner; class Solution { public static int superEggDrop1(int K, int N) { int v = log2N(N) + 1; if (K >= v) { return v; } int[][] dp = new int[N + 1][K + 1]; for (int i = 1; i <= N; ++i) { dp[i][1] = i; } for (int i = 1; i <= K; ++i) { dp[1][i] = 1; } for (int i = 2; i <= N; ++i) { for (int j = K; j >= 2; --j) { dp[i][j] = Integer.MAX_VALUE; for (int k = 1; k <= i; ++k) { if (dp[i][j] > Math.max(dp[i - k][j], dp[k - 1][j - 1]) + 1) { dp[i][j] = Math.max(dp[i - k][j], dp[k - 1][j - 1]) + 1; } } } } return dp[N][K]; } public static int superEggDrop2(int K, int N) { int v = (int) (Math.log(N) / Math.log(2)) + 1; if (K >= v) { return v; } int[][] dp = new int[N + 1][K + 1]; int[][] choose = new int[N + 1][K + 1]; for (int i = 1; i <= N; ++i) { dp[i][1] = i; choose[i][1] = 1; } for (int i = 1; i <= K; ++i) { dp[1][i] = 1; choose[1][i] = 1; } for (int i = 2; i <= N; ++i) { for (int j = K; j >= 2; --j) { dp[i][j] = Integer.MAX_VALUE; int down = Math.max(1, choose[i - 1][j]); int up = Math.min(j == K ? i : choose[i][j + 1], i); for (int k = down; k <= up; k++) { /** * 要更新右側格子,所以等於 */ if (dp[i][j] >= Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1) { dp[i][j] = Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1; choose[i][j] = k; } } } } return dp[N][K]; } /** * dp[i][j] * dp[0][j] = 0 * dp[i][0] = 0 * i 個蛋,扔 j 次達到的最大高度 * * @return */ public static int superEggDrop(int K, int N) { int v = (int) (Math.log(N) / Math.log(2)) + 1; if (K >= v) { return v; } int[] dp = new int[K + 1]; int ret = 0; while (true) { ret++; /** * dp[i][j] = dp[i][j - 1] + 1 + dp[i - 1][j - 1] * * 假設扔到最優位置 * * 1. 沒碎 * dp[i][j - 1] * * 2. 碎了 * dp[i - 1][j - 1] * */ int previous = 0, tmp; for (int i = 1; i <= K; ++i) { tmp = dp[i]; dp[i] = dp[i] + previous + 1; previous = tmp; if (dp[i] >= N) { return ret; } } } } public static int log2N(int n) { int res = -1; while (n != 0) { res++; n >>>= 1; } return res; } public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { System.out.println(superEggDrop(in.nextInt(), in.nextInt())); } } }