以下是问题描述:
假设我们想知道N层建筑中的哪些故事可以安全地从中掉落鸡蛋,哪些会导致鸡蛋在着陆时破裂。我们做了一些假设: 可以再次使用在摔倒后存活的鸡蛋。
考虑到N层建筑和d蛋的供应,找到了最小化(在最坏的情况下)确定断裂所需的实验滴数的策略。
我已经看到并解决了2个鸡蛋的问题,其中N = 100的答案是14。 我尝试使用DP了解wiki的通用解决方案,但无法理解他们想要做什么。请告诉他们他们是如何到达DP以及它是如何工作的?
编辑:
在this条款中给出的可用d滴和e蛋测试的最高层的复发如下:
f[d,e] = f[d-1,e] + f[d-1,e-1] + 1
复发很好,但我无法理解它是如何衍生的?
我的解释并不清楚......我只是希望有人用更清晰的话语向我解释这种情况。
答案 0 :(得分:10)
(1)考虑第一滴打破鸡蛋的情况。然后,当且仅当它最多为f [d-1,e-1]时,你才能确定地板。因此,你不能高于f [d-1,e-1] + 1(并且当然不应该从低点开始)。
(2)如果你的第一滴没有打破鸡蛋,你是f [d-1,e]的情况,只是从你的第一滴+ 1的地板开始而不是1楼。
所以,你能做的最好就是开始在f [d-1,e-1] + 1(因为(1))的地板上放鸡蛋,你可以起床f [d-1,e]楼层高于那个(因为(2))。这是
f[d, e] = f[d-1, e-1] + 1 + f[d-1, e]
答案 1 :(得分:9)
从Wiki Egg Dropping puzzle我们知道状态转移等式是:
W(n,k) = 1 + min{ max(W(n − 1, x − 1), W(n,k − x)) } , x = 1, 2, ..., k
W(n,1)=1, W(1,k)=k
n
=可用的试验蛋数量
k
=尚未测试的(连续)楼层数
以下是我的理解。
我们有k
个地板,n
个鸡蛋,假设我们在x
楼层使用鸡蛋进行测试。只有两种可能的结果:
x-1
楼层,n-1
鸡蛋,反映到W(n-1,x-1)
k-x
楼层,n
鸡蛋,反映到W(n,k-x)
由于问题需要最坏的情况,我们必须选择较大的问题以确保最坏的情况有效,这就是我们在W(n-1,x-1)
和W(n,k-x)
之间添加最大值的原因。
此外,正如我们假设在x
楼层进行测试,x
可以是1
到k
,在这种情况下,我们肯定需要选择最小值确保最小实验性下降找出N
,这就是为什么我们在{max(W(n − 1, x − 1), W(n,k − x)): x = 1, 2, ..., k}
之间添加分钟
最后,由于我们在x floor中使用1
drop,因此等式必须添加1
,这反映在等式的第一部分。
希望能解决你的难题: - )
答案 2 :(得分:0)
基于动态编程的解决方案 - http://algohub.blogspot.in/2014/05/egg-drop-puzzle.html
我相信这是不言自明的..请随意询问是否有任何部分不清楚......将乐意解释
答案 3 :(得分:0)
这个问题可以通过以下3种方法解决(我知道):
让我首先定义一些在之后进行的分析中使用的符号:
e = number of eggs
f = number of floors in building
n = number of egg drops
Fmax(e, n) = maximum number of floors that can be tested or covered with e eggs and n drops
动态编程方法的关键在于遵循Fmax的递归公式:
Fmax(e, n) = 1 + Fmax(e-1, n-1) + fmax(e, n-1)
获得Fmax的直接数学公式的关键在于遵循Fmax的递归公式:
Fmax(e, n) = { ∑Fmax(e-1,i) for i = 1 to n } - Fmax(e-1, n) + n
使用二进制搜索树(BST)的替代解决方案也可能解决此问题。为了便于我们的分析,让我们绘制BST,稍作修改如下:
1. If egg breaks then child node is drawn on left down side
2. If egg does not break then child node is drawn straight down side
如果我们用上面的表示法绘制BST,那么BST的宽度代表鸡蛋的数量。
任何具有f个节点的BST,用上述类型的表示绘制并受到BST <= e(蛋的数量)的约束宽度是一种解决方案,但它可能不是最佳解决方案。
因此,获得最优解决方案等同于获得BST中具有最小高度的节点的布置受到约束:BST的宽度<= e
有关上述所有3种方法的详细信息,请查看我的博客:3 approaches for solving generalized egg drop problem
答案 4 :(得分:0)
这个问题并不在于应该丢弃地板蛋的问题,而是要尽量减少掉落数量。
动态编程算法:
创建(totalEggs + 1)X(totalFloors + 1)的dp表
基础案例:当鸡蛋为零或一个时,设置为楼层i,表[0] [i] = 0;和表[1] [i] =我
基础案例:楼层为零或一,然后为鸡蛋j设置,表格[j] [0] = 0 和表[j] [1] = 1
将鸡蛋从2转换为total_eggs
public class EggDroppingPuzzle {
/** Not efficient **/
public static int solveByRecursion(int totalEggs, int totalFloors) {
/** Base Case: When no floor **/
if (totalFloors == 0) {
return 0;
}
/** Base case: When only one floor **/
if (totalFloors == 1) {
return 1;
}
/** Base case: When only one eggs, then we have to try it from all floors **/
if (totalEggs == 1) {
return totalFloors;
}
int minimumDrops = Integer.MAX_VALUE;
/** Now drop a egg from floor 1 to totalFloors **/
for (int k = 1; k <= totalFloors; k++) {
/** When an egg breaks at kth floor **/
int totalDropWhenEggBreaks = solveByRecursion(totalEggs - 1, k - 1);
/** When egg doesn't break at kth floor **/
int totalDropWhenEggNotBreaks = solveByRecursion(totalEggs, totalFloors - k);
/** Worst between above conditions **/
int maxDrop = Math.max(totalDropWhenEggBreaks, totalDropWhenEggNotBreaks);
/** Minimum drops for all floors **/
if (minimumDrops > maxDrop) {
minimumDrops = maxDrop;
}
}
return minimumDrops + 1;
}
public static int solveByByDP(int totalEggs, int totalFloors) {
int[][] table = new int[totalEggs + 1][totalFloors + 1];
/** Base Case: When egg is zero or one **/
for (int i = 0; i < totalFloors + 1; i++) {
table[0][i] = 0;
table[1][i] = i;
}
/** Base case: Floor is zero or one **/
for (int j = 0; j < totalEggs + 1; j++) {
table[j][0] = 0;
table[j][1] = 1;
}
/** For floor more than 1 and eggs are also more than 1 **/
for (int i = 2; i < totalEggs + 1; i++) {
for (int j = 2; j < totalFloors + 1; j++) {
table[i][j] = Integer.MAX_VALUE;
for (int k = 1; k <= j; k++) {
/** When an egg breaks at kth floor **/
int totalDropWhenEggBreaks = table[i - 1][k - 1];
/** When egg doesn't break at kth floor **/
int totalDropWhenEggNotBreaks = table[i][j - k];
/** Worst between above conditions **/
int maxDrop = 1 + Math.max(totalDropWhenEggBreaks, totalDropWhenEggNotBreaks);
/** Minimum drops for all floors **/
if (maxDrop < table[i][j]) {
table[i][j] = maxDrop;
}
}
}
}
return table[totalEggs][totalFloors];
}
}