号码选择游戏上的贪婪算法

时间:2018-12-05 21:12:49

标签: algorithm dynamic-programming greedy

问题如下:

有一个具有n个数字(a1,a2,a3,..,an)序列的游戏,并且有两个玩家。玩家从序列中获取数字;每回合,玩家可以选择序列中的第一个或最后一个数字。排空序列时,总赢额较大的玩家;如果相等,则游戏为平局。

目标是编写一个算法,该算法返回一个选择序列,以确保第一个玩家的最佳结果(获胜或平局),并假设第二个玩家将发挥最佳状态。

我想出了一个递归公式,可以将其转换为动态编程解决方案:

  • 对于序列Ai,Ai + 1,...,Aj:
  • 如果序列中有一个数字-请取下它。
  • 否则,请检查两个可能的选择,选择在游戏结束时第二个玩家的结果较低的一个。

因此,第一个玩家的最佳和是序列中所有数字的总和减去第二个玩家将获得的最小和。公式如下:

p(i,j)= Ai (如果i = j)

p(i,j)= Ai + Ai + 1 + ... + Aj-min {p(i + 1,j),p(i,j-1)} (如果是j> i)

我们使用相同的公式来计算第二个玩家的总和和第一个玩家的总和,因为第二个玩家也希望获得最大的可能值。

可以很容易地归纳证明其正确性。同样,我们可以从中获得动态编程解决方案:首先为每对(i,j)计算p(i,j)的值,并将其保存在表nxn中。该解取O(n ^ 3)。另外,还有一种方法可以对总和A1 + Ai + 1 + Ai + 2 + ... + Aj进行预处理:我们可以为每个j以及每次应用公式p来计算总和A1 + ... + Aj (i,j)可以使用sum(1,j)-sum(1,i),这样解将取O(n ^ 2)。

有更快的算法吗?在我的解决方案中,我得到了选择序列,该序列为第一个玩家提供了最大的总和,但这太“坚强”:我被要求获得使他获胜的一系列选择,而不管最终总和的最大化。因此,毫无疑问,我执行了一些不必要的步骤。

更好的解决方案似乎是一种贪婪算法,因为我已经看到了相同的问题,但是序列中的偶数个数字(此处为https://cs.stackexchange.com/questions/82351/optimizing-greedy-solution-for-choice-game/82450)。

有人能给我一些关于贪婪解决方案外观的想法或线索吗?预先谢谢你!

2 个答案:

答案 0 :(得分:1)

贪婪的解决方案意味着算法在每一步都会选择最佳的本地选项。在您的情况下,最佳本地选项将意味着在第一个元素和最后一个元素之间选择最大值。

关于贪婪算法的一些想法

专业人士

  • 易于实现

  • O(n)复杂时间

缺点

  • 算法可能停留在局部最小值

  • 最佳本地步骤并不总是最佳全局步骤,因此最终结果并不总是最佳结果

答案 1 :(得分:1)

“贪婪”是一个简单的概念:与其浏览整个游戏树,不如考虑使当前水平的短期结果最大化。在这种情况下,这意味着要采用两个可用元素中的较大者,而根本不使用递归。

您的完整解决方案,最大限度地增加了收到的资金,有效;对于一般情况来说,这只是一点点矫kill过正。

在两者之间取得平衡可能是有用的,一种启发式的方法可以预见一定的动作。例如,玩游戏时只向前移动四步(每位玩家两步),然后选择能使您的差异最大的一个。