鸡蛋掉落
作者:互联网
给你 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()));
}
}
}
标签:return,int,鸡蛋,static,dp,new,掉落,Math 来源: https://www.cnblogs.com/tianyiya/p/15455470.html