鸡蛋滴据/H1>据/HE.一种D.E.r>
测验据/H4.>据ul class="unstyled">
鸡蛋滴据/一种>据/span>
有关……据/H4.>据ul class="unstyled">
计算机科学据/span>>据/span>
贡献据/D.一世v>
鸡蛋滴据/strong>指的是一类问题,其中找到正确的响应是重要的,而不超过(低)某些故障状态。在玩具例子中,有一个塔据span class="katex">
N据/span>地板,还有一个鸡蛋滴管据span class="katex">
m据/span>理想的鸡蛋。理想蛋的物理性质使得如果它从地板上掉下来粉碎它据span class="katex">
N据/span>*据/span>或以上,如果它从地板掉落时,就不会损坏据span class="katex">
N据/span>*据/span>-据/span>1据/span>或下面。问题是找到一种策略,使得蛋滴可以确定地板据span class="katex">
N据/span>*据/span>在只有鸡蛋尽可能少。此问题在现实世界中有许多应用程序,例如避免呼叫慢HDD,或尝试最小化缓存未命中,或在数据库上运行大量昂贵的查询。据/p>
内容据/H4.>据ul class="unstyled">
2据/span>蛋,据span class="katex">
1据/span>0.据/span>0.据/span>地板据/一种>据/li>
2据/span>蛋,据span class="katex">
K.据/span>地板据/一种>据/li>
N据/span>蛋,据span class="katex">
K.据/span>地板据/一种>据/li>
递归解决方案据/一种>据/li>
DP的解决方案据/一种>据/li>
与二项式合作据/一种>据/li>
一个更好的方法据/一种>据/li>
也可以看看据/一种>据/li>
复杂据/一种>据/li>
2据/span>蛋,据span class="katex">
1据/span>0.据/span>0.据/span>地板据/H2>据/HE.一种D.E.r>
假设你有两个鸡蛋,你想确定一百楼建筑物中的哪个楼层,你可以放弃一个不会破裂的鸡蛋。您要确定在使用最佳策略的同时在最坏的情况下找到临界地板,确定您需要的最小次数。据/p>
- 如果鸡蛋在一定的地板上不打破,它不会在下面的任何楼层中断。据/li>
- 如果鸡蛋在某一层破裂,它就会在上面任何一层破裂。据/li>
- 鸡蛋可能会在一楼打破。据/li>
- 鸡蛋可能不会在最后一楼打破。据/li>
一个人需要使用二进制搜索解决这个问题,但实际上这不是最好的策略,你会看到原因。尝试自己解决这个问题并回答这个问题,或阅读,看看问题的详细说明。据/p>
使用二进制搜索,您必须从中删除第一个鸡蛋据span class="katex">
5.据/span>0.据/span>TH.据/span>地面。如果它不突破,你会从中掉下同一个鸡蛋据span class="katex">
7.据/span>5.据/span>TH.据/span>等等;在最好的情况下,你可以用7滴水覆盖所有楼层。据/p>
但如果你第一次尝试的时候鸡蛋破了,也就是据span class="katex">
5.据/span>0.据/span>TH.据/span>地面?如果发生这种情况,您有义务将剩余的鸡蛋从每个楼层放下直到找到据span class="katex">
N据/span>*据/span>,它有潜力据span class="katex">
4.据/span>9.据/span>删除测试,即据span class="katex">
O.据/span>(据/span>N据/span>)据/span>.据/p>
请记住,问题是确定临界楼层据span class="katex">
N据/span>*据/span>,所以在找到它之前,你不能让你的最后一个白蛋休息。从上一个鸡蛋放下你的最后一个鸡蛋据span class="katex">
2据/span>5.据/span>TH.据/span>地板是非常有风险的,因为如果它打破了你将无法确定临界地板。很明显,二进制搜索不是最佳解决方案。知道这一点,什么是最好的策略?你应该从哪个楼层开始?使用最佳策略时,您必须在最坏的情况下在最坏的情况下进行的最小滴数是多少?据/p>
从这一点开始据span class="katex">
1据/span>4.据/span>TH.据/span>地板是最好的策略,因为,正如我们将显示的那样,最坏情况下的尝试始终是14。据/p>
- 如果第一个鸡蛋在楼层14次休息怎么办?据B.r>如果第一个蛋突破据span class="katex">
1据/span>4.据/span>TH.据/span>地板,然后我们应该检查一楼,然后是第二个,直到据span class="katex">
1据/span>3.据/span>TH.据/span>地面。这样做的尝试总数为14。据/li>
- 如果它不破坏怎么办?据B.r>然后你应该检查一下据span class="katex">
2据/span>7.据/span>TH.据/span>地面。为什么?因为如果它破坏,你必须从中检查所有楼层据span class="katex">
1据/span>5.据/span>TH.据/span>直到据span class="katex">
2据/span>6.据/span>TH.据/span>一个(十三层),它保持14次尝试总数据span class="katex">
(据/span>第一次尝试据span class="katex">
1据/span>4.据/span>TH.据/span>地板,第二个据span class="katex">
2据/span>7.据/span>TH.据/span>地板,而且来自剩下的十二滴水据span class="katex">
1据/span>5.据/span>TH.据/span>地板,直到据span class="katex">
2据/span>6.据/span>TH.据/span>地面据span class="katex">
)据/span>.据/span>
如果它不破坏,你必须检查一下据span class="katex">
3.据/span>9.据/span>TH.据/span>地面;如果它破坏,你必须从中检查所有楼层据span class="katex">
2据/span>8.据/span>TH.据/span>直到据span class="katex">
3.据/span>8.据/span>TH.据/span>一个。据span class="katex">
(据/span>请记住,一次尝试据span class="katex">
1据/span>4.据/span>TH.据/span>地板,第二次尝试据span class="katex">
2据/span>7.据/span>TH.据/span>地板,第三次尝试据span class="katex">
3.据/span>9.据/span>TH.据/span>地板,楼层的11次尝试据span class="katex">
{据/span>2据/span>8.据/span>那据/span>2据/span>9.据/span>那据/span>3.据/span>0.据/span>那据/span>3.据/span>1据/span>那据/span>3.据/span>2据/span>那据/span>3.据/span>3.据/span>那据/span>3.据/span>4.据/span>那据/span>3.据/span>5.据/span>那据/span>3.据/span>6.据/span>那据/span>3.据/span>7.据/span>}据/span>38,在这种情况下,共计14次尝试。据span class="katex">
)据/span>
使用相同的推理,你应该检查一下据span class="katex">
5.据/span>0.据/span>TH.据/span>地板,楼据span class="katex">
6.据/span>0.据/span>TH.据/span>, 这据span class="katex">
6.据/span>9.据/span>TH.据/span>, 这据span class="katex">
7.据/span>7.据/span>TH.据/span>, 这据span class="katex">
8.据/span>4.据/span>TH.据/span>, 这据span class="katex">
9.据/span>0.据/span>TH.据/span>, 这据span class="katex">
9.据/span>5.据/span>TH.据/span>, 这据span class="katex">
9.据/span>9.据/span>TH.据/span>最后是据span class="katex">
1据/span>0.据/span>0.据/span>TH.据/span>一个。看到了吗?使用这种策略,你将覆盖所有楼层,尝试的次数永远不会超过14次,即使在最糟糕的情况下。据/p>
想知道这个表格如何看出3个鸡蛋!据/p>
使用其他策略,如二进制搜索,在某些情况下,在某些情况下需要更少的尝试(如在我们的第一个示例中),但它需要在最坏情况下需要大量的尝试据span class="katex">
(据/span>在我们的第二个例子中,鸡蛋在哪里崩溃了据span class="katex">
5.据/span>0.据/span>TH.据/span>在最坏的情况下,地板和50滴是必要的据span class="katex">
)据/span>.据/span>
因此,我们可以得出结论,使用其他策略在最坏的情况下需要超过14次尝试。据/p>
2据/span>蛋,据span class="katex">
K.据/span>地板据/H2>据/HE.一种D.E.r>
现在让我们试着找到一个解决方案,让你有2个鸡蛋和建筑物据span class="katex">
K.据/span>地板。据/p>
开始这个问题的好方法是问“我们是否能够覆盖所有的楼层据span class="katex">
X据/span>滴?“据/p>
假设在最好的策略中,最坏情况下的滴数是据span class="katex">
X据/span>.然后,你应该开始据span class="katex">
X据/span>TH.据/span>地板,因为如果鸡蛋破了,你必须检查地板据span class="katex">
1据/span>那据/span>2据/span>那据/span>3.据/span>那据/span>......据/span>那据/span>X据/span>-据/span>2据/span>和据span class="katex">
X据/span>-据/span>1据/span>,所以滴剂总数将是据span class="katex">
X据/span>.如果它不坏,你就得检查一下据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>)据/span>TH.据/span>地面。如果蛋休息,你将不得不检查楼层据span class="katex">
X据/span>+据/span>1据/span>那据/span>X据/span>+据/span>2据/span>那据/span>......据/span>那据/span>(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>-据/span>1据/span>)据/span>.因此,滴剂的数量将是据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>-据/span>1据/span>)据/span>-据/span>(据/span>X据/span>+据/span>1据/span>)据/span>+据/span>1据/span>+据/span>2据/span>=据/span>X据/span>.据/p>
你意识到我们在做什么吗?基于下降的数量始终如一的假设据span class="katex">
X据/span>在最坏的情况下,我们发现我们应该放弃鸡蛋的地板。这里的关键点是理解,我们并不试图找到最佳策略的最低次数;实际上,我们正试图找到最好的策略,假设最小滴数是据span class="katex">
X据/span>,我们必须最多确定是否使用所有楼层据span class="katex">
X据/span>尝试是可能的。据/p>
我们可以找到此问题的分析解决方案:据/p>
假设最坏情况下的最低尝试次数,同时使用最佳策略,是据span class="katex">
X据/span>.在我们的尝试中,我们会把鸡蛋放在据span class="katex">
X据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>楼层,然后我们把它放在据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>)据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>-据/span>1据/span>地板,第三滴将是据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>+据/span>(据/span>X据/span>-据/span>2据/span>)据/span>)据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>-据/span>2据/span>地板。我们可以看到使用这种策略我们会覆盖据/p>
X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>+据/span>(据/span>X据/span>-据/span>2据/span>)据/span>+据/span>(据/span>X据/span>-据/span>3.据/span>)据/span>+据/span>⋯据/span>+据/span>2据/span>+据/span>1据/span>=据/span>2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span>
地板。据/p>
如果我们能够覆盖据span class="katex">
2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span>使用这种策略和建筑物的地板据span class="katex">
K.据/span>地板,我们必须找到最低价值据span class="katex">
X据/span>这样据/p>
2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span>≥据/span>K.据/span>.据/span>
因此,据/p>
X据/span>2据/span>+据/span>X据/span>-据/span>2据/span>K.据/span>=据/span>0.据/span>⟹据/span>X据/span>=据/span>2据/span>-据/span>1据/span>+据/span>1据/span>+据/span>8.据/span>K.据/span>
.据/span>
但据span class="katex">
X据/span>必须是一个整数,暗示据/p>
X据/span>=据/span>⌈据/span>2据/span>-据/span>1据/span>+据/span>1据/span>+据/span>8.据/span>K.据/span>
⌉据/span>.据/span>
在我们的第一个例子中,据span class="katex">
K.据/span>=据/span>1据/span>0.据/span>0.据/span>,使将其插入前一个等式给出据span class="katex">
⌈据/span>1据/span>3.据/span>.据/span>6.据/span>5.据/span>⌉据/span>=据/span>1据/span>4.据/span>.据/p>
N据/span>蛋,据span class="katex">
K.据/span>地板据/H2>据/HE.一种D.E.r>
假设你有据span class="katex">
N据/span>鸡蛋,你想确定一个楼层据span class="katex">
K.据/span>-floor建筑你可以丢弃一个不会破裂的鸡蛋。您要确定在使用最佳策略的情况下在最坏情况下找到临界楼面的最低尝试次数。现在问题有点复杂了,因为我们必须找到任何数量的鸡蛋和地板的一般解决方案。有三种不同的解决方案:据/p>
递归解决方案:据B.r>这个解决方案更简单,也更容易实现,但它也是最慢的一个。不建议在编程竞赛中使用此解决方案,因为它的性能很差。据/p>
动态编程解决方案:据B.r>该解决方案类似于前一个,但它更快,并且可以用于解决中等或小值的问题据span class="katex">
K.据/span>和据span class="katex">
N据/span>.据/p>
将二进制搜索和递归组合的解决方案:据B.r>这是一个更快的一个,一旦策略被理解,它就很容易实现。据/p>
递归解决方案据/H2>据/HE.一种D.E.r>
想象一下以下情况:你有据span class="katex">
N据/span>鸡蛋和据span class="katex">
H据/span>连续楼层尚未进行测试,然后您将鸡蛋放在地板上据span class="katex">
一世据/span>在这个序列中据span class="katex">
H据/span>连续楼层:据/p>
如果蛋打破:据B.r>问题减少到据span class="katex">
N据/span>-据/span>1据/span>鸡蛋和据span class="katex">
一世据/span>-据/span>1据/span>剩余的楼层。据/p>
如果它不会破坏:据B.r>问题减少到据span class="katex">
N据/span>鸡蛋和据span class="katex">
H据/span>-据/span>一世据/span>剩余的楼层。这是一个重要的观点。我们想要测试的地板并不重要;事实上,剩余地板的数量是重要的。例如,测试1到20之间的楼层(包括1和20)需要相同数量的液滴来测试21到40之间或在81到100之间的地板。在所有三种情况下,我们测试了20层。据/p>
现在我们可以定义一个函数据span class="katex">
W.据/span>(据/span>N据/span>那据/span>H据/span>)据/span>计算在最糟糕的情况下,在最佳策略中计算在最坏的情况下找到关键地板所需的最小液滴数。据/p>
我们可以编写上述研究结果以查找以下递归以确定据span class="katex">
W.据/span>(据/span>N据/span>那据/span>H据/span>)据/span>:据/p>
鸡蛋掉落拼图的递归:据/strong>
W.据/span>[据/span>N据/span>那据/span>H据/span>]据/span>=据/span>1据/span>+据/span>闵据/span>(据/span>最大限度据/span>(据/span>W.据/span>(据/span>N据/span>-据/span>1据/span>那据/span>一世据/span>-据/span>1据/span>)据/span>那据/span>W.据/span>(据/span>N据/span>那据/span>H据/span>-据/span>一世据/span>)据/span>)据/span>)据/span>
(据/span>请注意:据span class="katex">
N据/span>=当前的鸡蛋数,据span class="katex">
N据/span>=鸡蛋总数,据span class="katex">
H据/span>=仍必须测试的连续楼层数量,据span class="katex">
K.据/span>=建筑物的数量。据span class="katex">
)据/span>
基本情况如下:据/p>
因为我们需要据span class="katex">
H据/span>如果只是据span class="katex">
1据/span>鸡蛋仍然存在,据span class="katex">
W.据/span>(据/span>1据/span>那据/span>H据/span>)据/span>=据/span>H据/span>.据/span>
因为我们只需要一个滴剂来测试一层,无论鸡蛋的数量如何,据span class="katex">
W.据/span>(据/span>N据/span>那据/span>1据/span>)据/span>=据/span>1据/span>.据/span>
因为0层楼不需要跌落,据span class="katex">
W.据/span>(据/span>N据/span>那据/span>0.据/span>)据/span>=据/span>0.据/span>.据/span>
该算法的伪代码由据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14据/pre>
def drops(n,h):if(n == 1或h == 0或h == 1):如果最小值= = x = 1到h:最小= min(最小,1 + max(滴(n - 1,x-1),滴(n,h - x)))结束以最低返回据/code>
C ++代码使用递归解决方案:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 2 21 22 23 32 32 29 29 32 32 32 32 32 32 32 32 42 43 44 44 44 44 44 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49据/pre>
#包括据/span>< iostream >据/span>#包括据/span>据/span>使用据/span>名称空间据/span>STD.据/span>;据/span>//比较2个值并返回更大的值据/span>int据/span>最大限度据/span>(据/span>int据/span>一种据/span>那据/span>int据/span>B.据/span>)据/span>{据/span>int据/span>ANS.据/span>=据/span>(据/span>一种据/span>>据/span>B.据/span>)据/span>还是据/span>一种据/span>:据/span>B.据/span>;据/span>返回据/span>ANS.据/span>;据/span>}据/span>//比较两个值并返回较小的值据/span>int据/span>闵据/span>(据/span>int据/span>一种据/span>那据/span>int据/span>B.据/span>){据/span>int据/span>ANS.据/span>=据/span>(据/span>一种据/span>据据/span>B.据/span>)据/span>还是据/span>一种据/span>:据/span>B.据/span>;据/span>返回据/span>ANS.据/span>;据/span>}据/span>int据/span>蛋据/span>(据/span>int据/span>N据/span>那据/span>int据/span>H据/span>){据/span>//基本情况据/span>如果据/span>(据/span>N据/span>==据/span>1据/span>)据/span>返回据/span>H据/span>;据/span>如果据/span>(据/span>H据/span>==据/span>0.据/span>)据/span>返回据/span>0.据/span>;据/span>如果据/span>(据/span>H据/span>==据/span>1据/span>)据/span>返回据/span>1据/span>;据/span>int据/span>最低据/span>=据/span>INT_MAX.据/span>;据/span>//找到鸡蛋的递归(n,k)。循环迭代I:1,2,3,...... H据/span>为了据/span>(据/span>int据/span>X据/span>=据/span>1据/span>;据/span>X据/span><=据/span>H据/span>;据/span>X据/span>++据/span>)据/span>最低据/span>=据/span>闵据/span>(据/span>最低据/span>,(据/span>1据/span>+据/span>最大限度据/span>(据/span>蛋据/span>(据/span>N据/span>那据/span>H据/span>-据/span>X据/span>),据/span>蛋据/span>(据/span>N据/span>-据/span>1据/span>那据/span>X据/span>-据/span>1据/span>))));据/span>返回据/span>最低据/span>;据/span>}据/span>int据/span>主要的据/span>()据/span>{据/span>int据/span>E.据/span>;据/span>/ /数量的鸡蛋据/span>int据/span>F据/span>;据/span>/ /层数据/span>COUT.据/span><<据/span>“鸡蛋掉落拼图据/span>\ n \ n据/span>鸡蛋数:“据/span>;据/span>cin据/span>>>据/span>E.据/span>;据/span>COUT.据/span><<据/span>“据/span>\ n据/span>地板数:“据/span>;据/span>cin据/span>>>据/span>F据/span>;据/span>COUT.据/span><<据/span>“据/span>\ n据/span>最坏情况下的滴滴数:“据/span><<据/span>蛋据/span>(据/span>E.据/span>那据/span>F据/span>);据/span>返回据/span>0.据/span>;据/span>}据/span>
DP的解决方案据/H2>据/HE.一种D.E.r>
以前的解决方案非常慢,并且相同的函数被称为多次,这是不必要的。但是,由于其重叠的子问题,并且其最佳子结构属性(我们可以使用子问题的最佳解决方案找到解决问题),我们可以通过动态编程来解决问题。据/p>
我们可以避免重新计算同一子问题据一种target="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/subroutines/">记忆据/一种>这个函数据code>鸡蛋(n,h)据/code>使用二维阵列据code>numdrops [n] [h]据/code>.然后,我们只需要填满它。据/p>
这是伪代码:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 13 14 15 16 18 19 20 21 21 22 23 22 22 22 27 22 22 22据/pre>
def solvepuzzle(n,k):对于i = 1到n numdrops(i,1)= 1 numdrops(i,0)= 0结束ig for i = 1到k numdrops(1,i)= i为i结束对于j = 2到k numdrops [i] [j] =∞最小= x为x = 1至j最小= min(最小,1 + max(numdrops(i-1,x-1),numdrops(一世那j-X)))E.ND.为了 numdrops[i][j] = minimum end for end for return numdrops(N,k)据/code>
C ++代码:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 21 22 23 32 32 32 29 32 32 32 32 32 32 42 42 43 42 43 44 44 44 44 49 49 49 49 45 49 49 4051 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 74 74据/pre>
#包括据/span>< iostream >据/span>#包括据/span>据/span>使用据/span>名称空间据/span>STD.据/span>;据/span>//比较2个值并返回更大的值据/span>int据/span>最大限度据/span>(据/span>int据/span>一种据/span>那据/span>int据/span>B.据/span>)据/span>{据/span>int据/span>ANS.据/span>=据/span>(据/span>一种据/span>>据/span>B.据/span>)据/span>还是据/span>一种据/span>:据/span>B.据/span>;据/span>返回据/span>ANS.据/span>;据/span>}据/span>//比较两个值并返回较小的值据/span>int据/span>闵据/span>(据/span>int据/span>一种据/span>那据/span>int据/span>B.据/span>){据/span>int据/span>ANS.据/span>=据/span>(据/span>一种据/span>据据/span>B.据/span>)据/span>还是据/span>一种据/span>:据/span>B.据/span>;据/span>返回据/span>ANS.据/span>;据/span>}据/span>int据/span>Solvepuzzle.据/span>(据/span>int据/span>N据/span>那据/span>int据/span>K.据/span>){据/span>int据/span>numdrops.据/span>[据/span>N据/span>+据/span>1据/span>][据/span>K.据/span>+据/span>1据/span>];据/span>int据/span>一世据/span>那据/span>j据/span>那据/span>X据/span>;据/span>为了据/span>(据/span>一世据/span>=据/span>0.据/span>;据/span>一世据/span><=据/span>K.据/span>;据/span>一世据/span>++据/span>)据/span>numdrops.据/span>[据/span>0.据/span>][据/span>一世据/span>]据/span>=据/span>0.据/span>;据/span>为了据/span>(据/span>一世据/span>=据/span>0.据/span>;据/span>一世据/span><=据/span>K.据/span>;据/span>一世据/span>++据/span>)据/span>numdrops.据/span>[据/span>1据/span>][据/span>一世据/span>]据/span>=据/span>一世据/span>;据/span>为了据/span>(据/span>j据/span>=据/span>0.据/span>;据/span>j据/span><=据/span>N据/span>;据/span>j据/span>++据/span>)据/span>numdrops.据/span>[据/span>j据/span>][据/span>0.据/span>]据/span>=据/span>0.据/span>;据/span>//这个循环填满了矩阵据/span>为了据/span>(据/span>一世据/span>=据/span>2据/span>;据/span>一世据/span><=据/span>N据/span>;据/span>一世据/span>++据/span>){据/span>为了据/span>(据/span>j据/span>=据/span>1据/span>;据/span>j据/span><=据/span>K.据/span>;据/span>j据/span>++据/span>){据/span>//将最低限定为最高可能值据/span>int据/span>最低据/span>=据/span>INT_MAX.据/span>;据/span>//评估1 + min {max(numeggs [i] [j-x],numeggs [i-1] [x-1])),用于x:1,2,3 ... j-1,j}据/span>为了据/span>(据/span>X据/span>=据/span>1据/span>;据/span>X据/span><=据/span>j据/span>;据/span>X据/span>++据/span>)据/span>最低据/span>=据/span>闵据/span>(据/span>最低据/span>,(据/span>1据/span>+据/span>最大限度据/span>(据/span>numdrops.据/span>[据/span>一世据/span>][据/span>j据/span>-据/span>X据/span>],据/span>numdrops.据/span>[据/span>一世据/span>-据/span>1据/span>][据/span>X据/span>-据/span>1据/span>
测验据/H4.>据ul class="unstyled">
有关……据/H4.>据ul class="unstyled">
鸡蛋滴据/strong>指的是一类问题,其中找到正确的响应是重要的,而不超过(低)某些故障状态。在玩具例子中,有一个塔据span class="katex"> N据/span>地板,还有一个鸡蛋滴管据span class="katex"> m据/span>理想的鸡蛋。理想蛋的物理性质使得如果它从地板上掉下来粉碎它据span class="katex"> N据/span>*据/span>或以上,如果它从地板掉落时,就不会损坏据span class="katex"> N据/span>*据/span>-据/span>1据/span>或下面。问题是找到一种策略,使得蛋滴可以确定地板据span class="katex"> N据/span>*据/span>在只有鸡蛋尽可能少。此问题在现实世界中有许多应用程序,例如避免呼叫慢HDD,或尝试最小化缓存未命中,或在数据库上运行大量昂贵的查询。据/p>
内容据/H4.>据ul class="unstyled">
2据/span>蛋,据span class="katex"> 1据/span>0.据/span>0.据/span>地板据/H2>据/HE.一种D.E.r>
假设你有两个鸡蛋,你想确定一百楼建筑物中的哪个楼层,你可以放弃一个不会破裂的鸡蛋。您要确定在使用最佳策略的同时在最坏的情况下找到临界地板,确定您需要的最小次数。据/p>
- 如果鸡蛋在一定的地板上不打破,它不会在下面的任何楼层中断。据/li>
- 如果鸡蛋在某一层破裂,它就会在上面任何一层破裂。据/li>
- 鸡蛋可能会在一楼打破。据/li>
- 鸡蛋可能不会在最后一楼打破。据/li>
一个人需要使用二进制搜索解决这个问题,但实际上这不是最好的策略,你会看到原因。尝试自己解决这个问题并回答这个问题,或阅读,看看问题的详细说明。据/p>
使用二进制搜索,您必须从中删除第一个鸡蛋据span class="katex">
5.据/span>0.据/span>TH.据/span>地面。如果它不突破,你会从中掉下同一个鸡蛋据span class="katex">
7.据/span>5.据/span>TH.据/span>等等;在最好的情况下,你可以用7滴水覆盖所有楼层。据/p>
但如果你第一次尝试的时候鸡蛋破了,也就是据span class="katex">
5.据/span>0.据/span>TH.据/span>地面?如果发生这种情况,您有义务将剩余的鸡蛋从每个楼层放下直到找到据span class="katex">
N据/span>*据/span>,它有潜力据span class="katex">
4.据/span>9.据/span>删除测试,即据span class="katex">
O.据/span>(据/span>N据/span>)据/span>.据/p>
请记住,问题是确定临界楼层据span class="katex">
N据/span>*据/span>,所以在找到它之前,你不能让你的最后一个白蛋休息。从上一个鸡蛋放下你的最后一个鸡蛋据span class="katex">
2据/span>5.据/span>TH.据/span>地板是非常有风险的,因为如果它打破了你将无法确定临界地板。很明显,二进制搜索不是最佳解决方案。知道这一点,什么是最好的策略?你应该从哪个楼层开始?使用最佳策略时,您必须在最坏的情况下在最坏的情况下进行的最小滴数是多少?据/p>
从这一点开始据span class="katex">
1据/span>4.据/span>TH.据/span>地板是最好的策略,因为,正如我们将显示的那样,最坏情况下的尝试始终是14。据/p>
如果它不破坏,你必须检查一下据span class="katex">
3.据/span>9.据/span>TH.据/span>地面;如果它破坏,你必须从中检查所有楼层据span class="katex">
2据/span>8.据/span>TH.据/span>直到据span class="katex">
3.据/span>8.据/span>TH.据/span>一个。据span class="katex">
(据/span>请记住,一次尝试据span class="katex">
1据/span>4.据/span>TH.据/span>地板,第二次尝试据span class="katex">
2据/span>7.据/span>TH.据/span>地板,第三次尝试据span class="katex">
3.据/span>9.据/span>TH.据/span>地板,楼层的11次尝试据span class="katex">
{据/span>2据/span>8.据/span>那据/span>2据/span>9.据/span>那据/span>3.据/span>0.据/span>那据/span>3.据/span>1据/span>那据/span>3.据/span>2据/span>那据/span>3.据/span>3.据/span>那据/span>3.据/span>4.据/span>那据/span>3.据/span>5.据/span>那据/span>3.据/span>6.据/span>那据/span>3.据/span>7.据/span>}据/span>38,在这种情况下,共计14次尝试。据span class="katex">
)据/span> 使用相同的推理,你应该检查一下据span class="katex">
5.据/span>0.据/span>TH.据/span>地板,楼据span class="katex">
6.据/span>0.据/span>TH.据/span>, 这据span class="katex">
6.据/span>9.据/span>TH.据/span>, 这据span class="katex">
7.据/span>7.据/span>TH.据/span>, 这据span class="katex">
8.据/span>4.据/span>TH.据/span>, 这据span class="katex">
9.据/span>0.据/span>TH.据/span>, 这据span class="katex">
9.据/span>5.据/span>TH.据/span>, 这据span class="katex">
9.据/span>9.据/span>TH.据/span>最后是据span class="katex">
1据/span>0.据/span>0.据/span>TH.据/span>一个。看到了吗?使用这种策略,你将覆盖所有楼层,尝试的次数永远不会超过14次,即使在最糟糕的情况下。据/p>
想知道这个表格如何看出3个鸡蛋!据/p>
使用其他策略,如二进制搜索,在某些情况下,在某些情况下需要更少的尝试(如在我们的第一个示例中),但它需要在最坏情况下需要大量的尝试据span class="katex">
(据/span>在我们的第二个例子中,鸡蛋在哪里崩溃了据span class="katex">
5.据/span>0.据/span>TH.据/span>在最坏的情况下,地板和50滴是必要的据span class="katex">
)据/span>.据/span> 因此,我们可以得出结论,使用其他策略在最坏的情况下需要超过14次尝试。据/p>
2据/span>蛋,据span class="katex"> K.据/span>地板据/H2>据/HE.一种D.E.r>
现在让我们试着找到一个解决方案,让你有2个鸡蛋和建筑物据span class="katex"> K.据/span>地板。据/p>
开始这个问题的好方法是问“我们是否能够覆盖所有的楼层据span class="katex"> X据/span>滴?“据/p>
假设在最好的策略中,最坏情况下的滴数是据span class="katex">
X据/span>.然后,你应该开始据span class="katex">
X据/span>TH.据/span>地板,因为如果鸡蛋破了,你必须检查地板据span class="katex">
1据/span>那据/span>2据/span>那据/span>3.据/span>那据/span>......据/span>那据/span>X据/span>-据/span>2据/span>和据span class="katex">
X据/span>-据/span>1据/span>,所以滴剂总数将是据span class="katex">
X据/span>.如果它不坏,你就得检查一下据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>)据/span>TH.据/span>地面。如果蛋休息,你将不得不检查楼层据span class="katex">
X据/span>+据/span>1据/span>那据/span>X据/span>+据/span>2据/span>那据/span>......据/span>那据/span>(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>-据/span>1据/span>)据/span>.因此,滴剂的数量将是据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>-据/span>1据/span>)据/span>-据/span>(据/span>X据/span>+据/span>1据/span>)据/span>+据/span>1据/span>+据/span>2据/span>=据/span>X据/span>.据/p>
你意识到我们在做什么吗?基于下降的数量始终如一的假设据span class="katex">
X据/span>在最坏的情况下,我们发现我们应该放弃鸡蛋的地板。这里的关键点是理解,我们并不试图找到最佳策略的最低次数;实际上,我们正试图找到最好的策略,假设最小滴数是据span class="katex">
X据/span>,我们必须最多确定是否使用所有楼层据span class="katex">
X据/span>尝试是可能的。据/p>
我们可以找到此问题的分析解决方案:据/p>
假设最坏情况下的最低尝试次数,同时使用最佳策略,是据span class="katex">
X据/span>.在我们的尝试中,我们会把鸡蛋放在据span class="katex">
X据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>楼层,然后我们把它放在据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>)据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>-据/span>1据/span>地板,第三滴将是据span class="katex">
(据/span>X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>+据/span>(据/span>X据/span>-据/span>2据/span>)据/span>)据/span>TH.据/span>地板,覆盖据span class="katex">
X据/span>-据/span>2据/span>地板。我们可以看到使用这种策略我们会覆盖据/p>
X据/span>+据/span>(据/span>X据/span>-据/span>1据/span>)据/span>+据/span>(据/span>X据/span>-据/span>2据/span>)据/span>+据/span>(据/span>X据/span>-据/span>3.据/span>)据/span>+据/span>⋯据/span>+据/span>2据/span>+据/span>1据/span>=据/span>2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span> 地板。据/p>
如果我们能够覆盖据span class="katex">
2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span>使用这种策略和建筑物的地板据span class="katex">
K.据/span>地板,我们必须找到最低价值据span class="katex">
X据/span>这样据/p>
2据/span>X据/span>(据/span>X据/span>+据/span>1据/span>)据/span>≥据/span>K.据/span>.据/span> 因此,据/p>
X据/span>2据/span>+据/span>X据/span>-据/span>2据/span>K.据/span>=据/span>0.据/span>⟹据/span>X据/span>=据/span>2据/span>-据/span>1据/span>+据/span>1据/span>+据/span>8.据/span>K.据/span>
.据/span> 但据span class="katex">
X据/span>必须是一个整数,暗示据/p>
X据/span>=据/span>⌈据/span>2据/span>-据/span>1据/span>+据/span>1据/span>+据/span>8.据/span>K.据/span>
⌉据/span>.据/span> 在我们的第一个例子中,据span class="katex">
K.据/span>=据/span>1据/span>0.据/span>0.据/span>,使将其插入前一个等式给出据span class="katex">
⌈据/span>1据/span>3.据/span>.据/span>6.据/span>5.据/span>⌉据/span>=据/span>1据/span>4.据/span>.据/p>
N据/span>蛋,据span class="katex"> K.据/span>地板据/H2>据/HE.一种D.E.r>
假设你有据span class="katex"> N据/span>鸡蛋,你想确定一个楼层据span class="katex"> K.据/span>-floor建筑你可以丢弃一个不会破裂的鸡蛋。您要确定在使用最佳策略的情况下在最坏情况下找到临界楼面的最低尝试次数。现在问题有点复杂了,因为我们必须找到任何数量的鸡蛋和地板的一般解决方案。有三种不同的解决方案:据/p>
递归解决方案:据B.r>这个解决方案更简单,也更容易实现,但它也是最慢的一个。不建议在编程竞赛中使用此解决方案,因为它的性能很差。据/p>
动态编程解决方案:据B.r>该解决方案类似于前一个,但它更快,并且可以用于解决中等或小值的问题据span class="katex"> K.据/span>和据span class="katex"> N据/span>.据/p>
将二进制搜索和递归组合的解决方案:据B.r>这是一个更快的一个,一旦策略被理解,它就很容易实现。据/p>
递归解决方案据/H2>据/HE.一种D.E.r>
想象一下以下情况:你有据span class="katex"> N据/span>鸡蛋和据span class="katex"> H据/span>连续楼层尚未进行测试,然后您将鸡蛋放在地板上据span class="katex"> 一世据/span>在这个序列中据span class="katex"> H据/span>连续楼层:据/p>
如果蛋打破:据B.r>问题减少到据span class="katex"> N据/span>-据/span>1据/span>鸡蛋和据span class="katex"> 一世据/span>-据/span>1据/span>剩余的楼层。据/p>
如果它不会破坏:据B.r>问题减少到据span class="katex"> N据/span>鸡蛋和据span class="katex"> H据/span>-据/span>一世据/span>剩余的楼层。这是一个重要的观点。我们想要测试的地板并不重要;事实上,剩余地板的数量是重要的。例如,测试1到20之间的楼层(包括1和20)需要相同数量的液滴来测试21到40之间或在81到100之间的地板。在所有三种情况下,我们测试了20层。据/p>
现在我们可以定义一个函数据span class="katex">
W.据/span>(据/span>N据/span>那据/span>H据/span>)据/span>计算在最糟糕的情况下,在最佳策略中计算在最坏的情况下找到关键地板所需的最小液滴数。据/p>
我们可以编写上述研究结果以查找以下递归以确定据span class="katex">
W.据/span>(据/span>N据/span>那据/span>H据/span>)据/span>:据/p>
鸡蛋掉落拼图的递归:据/strong>
W.据/span>[据/span>N据/span>那据/span>H据/span>]据/span>=据/span>1据/span>+据/span>闵据/span>(据/span>最大限度据/span>(据/span>W.据/span>(据/span>N据/span>-据/span>1据/span>那据/span>一世据/span>-据/span>1据/span>)据/span>那据/span>W.据/span>(据/span>N据/span>那据/span>H据/span>-据/span>一世据/span>)据/span>)据/span>)据/span>
(据/span>请注意:据span class="katex">
N据/span>=当前的鸡蛋数,据span class="katex">
N据/span>=鸡蛋总数,据span class="katex">
H据/span>=仍必须测试的连续楼层数量,据span class="katex">
K.据/span>=建筑物的数量。据span class="katex">
)据/span> 基本情况如下:据/p>
因为我们需要据span class="katex">
H据/span>如果只是据span class="katex">
1据/span>鸡蛋仍然存在,据span class="katex">
W.据/span>(据/span>1据/span>那据/span>H据/span>)据/span>=据/span>H据/span>.据/span> 因为我们只需要一个滴剂来测试一层,无论鸡蛋的数量如何,据span class="katex">
W.据/span>(据/span>N据/span>那据/span>1据/span>)据/span>=据/span>1据/span>.据/span> 因为0层楼不需要跌落,据span class="katex">
W.据/span>(据/span>N据/span>那据/span>0.据/span>)据/span>=据/span>0.据/span>.据/span>
该算法的伪代码由据/p>
C ++代码使用递归解决方案:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14据/pre>
def drops(n,h):if(n == 1或h == 0或h == 1):如果最小值= = x = 1到h:最小= min(最小,1 + max(滴(n - 1,x-1),滴(n,h - x)))结束以最低返回据/code>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 2 21 22 23 32 32 29 29 32 32 32 32 32 32 32 32 42 43 44 44 44 44 44 49 49 49 49 49 49 49 49 49 49 49 49 49 49 49据/pre>
#包括据/span>< iostream >据/span>#包括据/span>
DP的解决方案据/H2>据/HE.一种D.E.r>
以前的解决方案非常慢,并且相同的函数被称为多次,这是不必要的。但是,由于其重叠的子问题,并且其最佳子结构属性(我们可以使用子问题的最佳解决方案找到解决问题),我们可以通过动态编程来解决问题。据/p>
我们可以避免重新计算同一子问题据一种target="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/subroutines/">记忆据/一种>这个函数据code>鸡蛋(n,h)据/code>使用二维阵列据code>numdrops [n] [h]据/code>.然后,我们只需要填满它。据/p>
这是伪代码:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 13 14 15 16 18 19 20 21 21 22 23 22 22 22 27 22 22 22据/pre> |
|
C ++代码:据/p>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 21 22 23 32 32 32 29 32 32 32 32 32 32 42 42 43 42 43 44 44 44 44 49 49 49 49 45 49 49 4051 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 74 74据/pre> |
|