Peg Game:放置球的最佳位置,使其落在目标细胞中

时间:2011-01-11 11:12:37

标签: algorithm math statistics

来源:Facebook Hacker Cup Qualification Round 2011

在街机游戏中,您可以从您选择的位置玩一个简单的游戏,其中一个球落入游戏的顶部。当球落入游戏时,球会弹出许多钉子。每当球击中一个钉子时,它将以0.5的概率反弹到左边,并以0.5的概率向右反弹。唯一的例外是当它击中最左侧或右侧的钉子时,在这种情况下它总是向中间弹跳。

当游戏首次制作时,钉子以规则网格排列。然而,这是一个老游戏,现在一些钉子丢失了。你在游戏中的目标是让球在特定位置脱离游戏的底部。鉴于游戏的安排,我们如何确定丢球的最佳位置,以便将其送到这个特定位置的概率最大化?

下图显示了一个包含五行五列的游戏示例。请注意,顶行有五个钉,下一行有四个钉,接下来五个,依此类推。有五个列,有四种选择可以将球放入(从0开始索引)。请注意,在此示例中,缺少三个挂钩。第一行是第0行,最左边的第二行是第0列,因此缺失钉的坐标是(1,1),(2,1)和(3,2)。在这个例子中,丢球的最佳位置是在第0列的最左侧,这使得它有50%的几率在目标中结束。

x.x.x.x.x
 x...x.x
x...x.x.x
 x.x...x
x.x.x.x.x
 G

x表示挂钩,.表示空格。

5 个答案:

答案 0 :(得分:4)

从底部开始,为目标指定1的概率,为其他位置指定0的概率。然后对于下一行,按如下方式分配概率:

1) if there is no peg, use the probability directly below.
2) for a peg, use the average of the probabilities in the adjacent columns one row down.

这将简单地将概率传播到顶部,其中每个槽将被分配从该槽到达目标的概率。没有树,没有递归。

答案 1 :(得分:2)

我们可以使用概率论来解决这个问题。我们将球放在一个位置,并递归地将球的路径分成一个(在侧壁)或两个可能的方向。在第一步,我们以概率1知道球的位置(毕竟我们正在放弃它!)。在随后分成两个方向时,概率减半。如果我们最终位于目标位置的底行,我们将路径的概率添加到总计。对所有起始位置重复此过程,并达到达到目标的最高概率。

我们可以通过使用动态编程去除递归和逐行处理来改进此算法。从设置为全0的第一行开始,除了我们设置为1的起始位置。然后通过从0和0的数组开始计算到达下一行中每个单元的概率。对于当前行中的每个单元格,将其概率的一半加到下一行的左侧单元格中,将其一半加到右侧,除非它靠近侧壁,在这种情况下我们将完全概率添加到单个单元格。继续为每一行执行此操作,直到到达最后一行。

到目前为止,我们忽略了失踪的钉子。我们可以通过对每个单元格具有三个概率来考虑它们:一个球体当前行进的每个方向。最后,我们总结所有因为方向无关紧要。

答案 2 :(得分:0)

这个问题出现在2011年的Facebook黑客杯中。

marcog解决方案似乎是正确的,但我解决了一点不同。我这样解决了:

  1. 设置板:读取输入,设置NxM板,读取缺失的钉并在板上插入孔。
  2. 对于每个可能的初始丢弃孔,按照以下步骤执行BFS:

    • 掉落洞的初始概率为1.0。
    • 从当前状态开始,您可以向下,向左,向右,向左和向右移动。
    • 如果您只能向下,向左或向右移动,请将当前状态概率相加,并将其添加到队列中(如果它尚未在队列中)。例如:如果你在概率为0.5的(1,2)并且只能下降,则将0.5加到状态(2,2)并将其添加到队列中(如果它已经不在队列中)。
    • 如果您可以向左和向右移动,则将当前状态概率的一半加到每个可能的下一个状态,如果它们尚未存在,则将它们添加到队列中。例如:如果你处于(3,3),概率为0.5并且可以左右两次,则将0.25添加到(4,2)和0.25到(4,4)并将它们添加到队列中(如果它们尚未存在) 。
  3. 最新更新
  4. 打印全球最佳。
  5. 我在cpp中的解决方案(不是最干净的代码)可以从以下网址下载:https://github.com/piva/Programming-Challenges/blob/master/peggame.cpp

    希望有帮助...

答案 3 :(得分:0)

观察:

  1. 对于给定的起始位置,每行都有概率分布
  2. 从一个完整行到下一行,除边缘外,分布将简单模糊。
  3. 如果有漏洞,我们会看到(2)
  4. 中模糊的可预测偏差
  5. 我们可以将这些偏差分开,因为球一次一个地掉落,所以概率遵循叠加原则(量子计算机在这里是理想的)。
  6. 分离出偏差,我们可以看到实际上有一组孔叠在一个钉子的网格上,所以我们可以先从整套钉子中计算出来的分布(简单),然后分别通过钉子来计算看到它们的效果 - 这假设有更多的钉子而不是孔!
  7. 边缘实际上是一面镜子 - 我们可以计算这些镜像虚拟板的无限数组,而不是使用if条件作为边界。
  8. 所以我会从底部开始,处于理想的位置,然后分散概率。缺失的钉子实际上只是跳过一排,所以你保留一个垂直落球的记录。

    理想情况下,我会从一个完整的(斐波那契)树开始,并且对于每一行中缺失的钉子,会增加它们缺失的效果。

答案 4 :(得分:0)

O(R*C)解决方案

dp[i][j]给出球到达目标位置的概率,如果它当前位于第i行和第j行。

基本案例有dp[R-1][goal] = 1.0,第R-1行的所有其他广告位都有0.0

然后重现

dp[i][j] = dp[i + 2][j] if the peg below is missing 
dp[i][j] = dp[i + 1][left] if the peg is on the right wall 
dp[i][j] = dp[i + 1][right] if the peg is on the left wall 
dp[i][j] = (dp[i + 1][left] + dp[i + 1][right]) / 2 otherwise