http://datagenetics.com/blog/july22012/index.html
我正在使用上述链接来了解鸡蛋滴问题。我也看过网上的一些代码,这些代码我都相当了解(递归有些混乱),但是我似乎无法理解有关此掉蛋问题的一些主要知识。
假设我们有100层
对于2个鸡蛋,我们说我们从14开始,然后转到14 +(14-1)。我了解为什么我们要这样做以保持更糟的情况下的时间统一。但是,我们从哪里开始生三个鸡蛋呢?该公式显示,在最坏的情况下,三个鸡蛋最多可以进行9次尝试。显然,我们不是从9开始,因为进行9 +(9-1)不会给我们100个包含9次的连续试验,那么我们从3开始的地方呢?不仅如此,我们如何解决呢?
似乎对于3个鸡蛋,我们进行了几次试验,直到问题退化为2个鸡蛋和x层的地板。从概念上讲这很有意义,但我不明白如何形象化或实现
我必须在最坏的情况下找到尝试的顺序并加以实现,这就是为什么我要可视化尝试的原因。
我希望这很清楚。这是我的第一个主要问题。如果我丢失任何信息,请告诉我,我将对其进行编辑。
最佳答案
方程n(n + 1)/ 2 = F仅可用于求解在2个蛋的情况下最小的最坏情况下的液滴数。由于提到的均匀性,这里也恰好是您可以放下第一个鸡蛋的地板之一。您知道您可以从14楼跌落,因为如果破裂,您将有至少13滴落下。但是,如果它没有破裂,而您爬上13层并且破裂,那么在最坏的情况下,您将再有12滴下落,其中2滴已经下落。通过这种模式,您可以看到,从n楼,n +(n-1)楼,n +(n-1)+(n-2)楼放鸡蛋,最坏的情况是每个阈值都保持不变。
这是您想要达到的目标,而不管开始时有多少个鸡蛋,但是无法用以下公式计算出使该条件成立的最佳下限(n)(实际上可以表示为@Amit指出的范围)。像一个封闭的系列,可以装两个鸡蛋。重要的是要注意,即使在(n + 1)n = F的情况下,n只是可能的第一底值的许多答案之一。我们很方便地说这是答案,也许是粗心大意,因为我们可以使用一个相对简单的序列证明它是正确的。
因此,让我们使用一种更通用的方法来估计最小的最坏情况下的墨滴数,然后看看我们知道可以在哪些楼层上实现此目的。假设我们有g(floors, eggs)
函数,该函数返回特定数量的地板所需的最坏情况下的最小蛋滴数。我们可以放心地说,如果eggs = 1
,最坏的情况是我们必须从每一层都扔鸡蛋才能找到阈值,因此g(floors, 1) = floors
对于任何floors
值都是正确的。我们也知道,如果我们有1层楼要测试,它总是只需要下降一滴,所以g(1, eggs) = 1
。除了这两种情况,我们还了解以下内容:g(floors, eggs) = Min(n = 1->floors : 1 + max(g(n-1,e-1),g(floors-n, e)))
为什么行得通?考虑到总楼层数,每个楼层都必须经过一个楼层,看看在每个楼层开裂鸡蛋的最坏情况是什么。通过比较最坏的情况(如果破裂或g([current floor]-1, eggs-1)
)和最坏的情况(如果不破裂或g(floors-[current floor], eggs)
)来完成此操作。
对于该特定楼层,这两个值的最大值将是最坏的情况。如果我们跟踪每个最大值的全局最小值,那么我们将找到最坏情况下所需的最低滴。发生这种情况的地板是放置鸡蛋的最佳地板。现在,让我们在该函数中插入eggs = 2
可以更好地了解其工作原理,以及为什么我们也可以表示从两个鸡蛋序列开始时的最小最坏情况下滴数。
当我们恰好有2个鸡蛋时,我们将始终将g([current floor]-1, 1)
与g(floors-[current floor], 2)
进行比较。这使事情变得容易一些,因为我们确切地知道如果在当前地板上破鸡蛋,最坏的情况是什么:*worst case drops required* = g(cf-1, 1) + 1 = 1 + (cf-1)
注意-在这里我们添加1是因为在测试下面的其余楼层时我们已经完成了1滴落。
我们还知道,对于固定的总楼层数F,在每个楼层(cf)上比较的两个函数都在两个不同的方向上单调前进。这必须成立,因为:g(cf+d, 1) > g(cf, 1)
对于任何正cf和d,因此此功能随着cf的增加而增加。g(F-(cf+d),2) < g(F-cf,2)
,因此此功能始终会随着cf的增加而减小。
上面的内容很重要,因为它使我们意识到这两个函数的最小最大值将发生在一个返回彼此最接近的值的地板上(我们称其为最佳地板),甚至可以说等于彼此!使用此函数,我们可以估算出最小值在以下情况下发生:
g(of1-1,1)〜= of1-1〜= g(F- of1,2)〜= 1+(of2-1)〜= 1+ g(F- of1-of2,2)〜= 2+ (of3-1)〜= .....〜= of2->右边最远的值代表最坏的情况,如果鸡蛋未在任何最佳阈值下破裂,那么我们将用光2个数字到达该点的滴数,不算第一个滴。
其中,of1是理论下限,在该上限下可能会发生第一个跌落,以最大程度地减少最坏的情况; of1 + of2是第二个跌落必须发生的位置(鉴于在of1处开裂失败),一直上升到of1 + of2 ... + ofn =F。现在让我们检查of1和of2之间的关系:
(of1-1)= 1+(of2-1),因此of2 = of1-1
类似地
的3 =的2 -1 =的1-2
最后我们可以说一般
ofn = of1-(n-1)
我们知道,如果我们经过了除最后一个阈值以外的所有阈值限制,并且没有一个破获鸡蛋,那么我们就处于第一个下降点。
ofof1 = of1-(of1-1)= 1 =>此元素是我们系列中的最后一个
of1 + of2 ... + ofn的级数可以写成of1 +(of1-1)+(of1-2)+ .... + 1 = F,我们知道它可以表示为(of1)(of1 + 1)/ 2 =F。这使得找到最小的最差情况下的投掷次数和使第一个鸡蛋掉下的最佳下场数成为将F插入此公式的简单练习。
好吧,现在当鸡蛋等于三时,我们使用相同的功能!不幸的是,事实证明您是在第一步中碰壁的。还记得我们还在比较g([current floor]-1, eggs-1)
和g(floors-[current floor], eggs)
的时候吗?好吧,现在说eggs = 3
,所以您正在比较g(floors-[current floor], 3)
和g([current floor]-1, 2)
。
我们不能将这些函数中的任何一个归结为以封闭形式的解决方案作为函数的序列g(F - cf, 3)
需要至少一个递归级别来求解,因此无论我们将其简化为多少,都将始终具有带g函数的项。另一方面,如果我们尝试利用事实g(f-1, 2)
存在一个n
,其中(n+1)n/2 = f-1
,其中n是最小最坏情况下的丢弃次数。
如果我们将(n+1)n/2 = f-1
重新排列为n = 1/2(sqrt(8f-7)-1) = g(f-1, 2)
我们可能会尝试将g(of1-1,2)设置为等于1 + g(of2-1,2)来查找of2作为of1的函数,类似于我们发现当以2个蛋。如果您还记得的话,我们将所有“最佳”滴落物放置在一个碰巧具有封闭形式解决方案的系列中,以第一个滴落的最佳落物表示。有了3个鸡蛋,我们就没运气了,因为这将导致“丑陋”的系列,没有递归就无法解决。这与我们从两个鸡蛋开始的情况不同,因为我们能够将g(cf-1, 1) + 1
减少为1 + (cf-1)
。这帮助我们构建了确实具有封闭式解决方案的系列。
因此,没有像2个蛋的情况那样找到最佳的第一滴的巧妙推导。在下面,我写了一个简短的算法,可以输出最小的最坏情况下的丢包数和最适合第一次丢包的下限(通常它可以超过一个,但我总是返回最后一个)。将e的值设置为2以外的值后,您会发现这些值不一定彼此相等。
var optimumFloorForFirstDrop = 0;
var F = 24;
console.log("Minimum worst case number of drops: " +findBestWorstCase(F,3) + ", optimum floor for first drop: "+ optimumFloorForFirstDrop);
function findBestWorstCase(n, e){
//if we have 0 or 1 floors or one egg then return the number of floor...this is pretty intuitive
if(n < 2 || e == 1) return n;
//we want to go through every floor and keep track of the minimum for a particular n of the max function below
var min = n;
for(var i = 1; i <= n; i++){
var tmpMax = 1 + Math.max(findBestWorstCase(i-1, e-1),findBestWorstCase(n-i, e));
if(tmpMax <= min){
min = tmpMax;
if(n==F) optimumFloorForFirstDrop = i;
}
}
return min;
}
关于algorithm - 了解不止两个鸡蛋的减蛋算法。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40118972/