最佳去除K个硬币后选择最大金额的游戏

时间:2019-04-01 11:10:25

标签: algorithm dynamic-programming

我有以下任务要解决:
两个玩家玩游戏。在这个游戏中有硬币,每个硬币都有一个值。每个玩家轮流选择1个硬币。目标是最终获得最高的总价值。每个玩家都必须选择玩(这意味着始终从堆中选择最高值)。我必须找出2位玩家的总和/他们最高的总和之间的差额

约束:所有值均为自然整数且为正。

上面的任务是一个经典的贪婪问题。根据我的尝试,可以使用quickSort对其进行排序,然后只为2个玩家选择元素。如果您在测试中需要更好的时间,则Radix-Sort的性能会更好。好了,这个任务很简单。

现在我的任务与上述相同,但第一个玩家必须删除OPTIMALLY K个硬币,以使它们的得分之间的差异最大。听起来像DP,但我无法解决。我必须再次找出他们的得分之间的最大差额(两名球员均处于最佳状态)。或者说,这两个玩家的得分之间的差异最大。

是否已经实施了这样的算法?或者有人可以给我一些有关此问题的提示吗?

1 个答案:

答案 0 :(得分:1)

这是DP方法解决方案。我们考虑n个硬币,按降序排序以简化表示法(这意味着coins[0]是最高价值的硬币,而coins[n-1]是最低价值的硬币),并且我们想删除{{1 }}硬币以赢得尽可能多的利润。
我们将考虑一个k维度为M的矩阵n-k
k存储以下内容:M是经过M(i, j)个硬币而从i的最佳状态中移除后j个回合后可能的最高得分硬币。乍一看可能听起来有点违反直觉,但这实际上是我们正在寻找的。
实际上,我们已经有一个值可以初始化矩阵:i+j
我们还可以看到M(0, 0) = 0实际上是我们要解决的问题的解决方案。
现在,我们需要递归方程来填充矩阵。我们认为我们想最大化第一个玩家的得分差异。为了最大化第二名玩家的得分差异,方法是相同的,只是修改一些符号。

M(n-k, k)

这种重复只是意味着,在任何时候,最好的选择是在删除硬币(在最佳值为if i = 0 then: M(i, j) = 0 // score difference is always 0 after playing 0 turns else if j = 0 and i % 2 = 0: // player 1 plays M(i, j) = M(i-1, j) + coins[i+j] else if j = 0 and i % 2 = 1: // player 2 plays M(i, j) = M(i-1, j) - coins[i+j] else if i % 2 = 0: M(i, j) = max(M(i, j-1), M(i-1, j) + coins[i+j]) else if i % 2 = 1: M(i, j) = max(M(i, j-1), M(i-1, j) - coins[i+j]) 的情况下)还是不删除硬币(在最佳值为{{的情况下) 1}})。
这将给您最终的分数差异,但不会消除要删除的硬币组。要找到它,您必须保留程序用于计算矩阵值的“最佳路径”(最佳值是来自M(i-1,j)还是来自M(i,j-1)?)。 br /> 此路径可以为您提供所需的设置。顺便说一句,您可以看到这是有道理的,因为有M(i, j-1)种可能的方法可以从M(i-1, j) +/- coins[i+j]个硬币中删除k among n个硬币,并且还有k个路径如果只允许您向右或向下移动,则按n的{​​{1}}矩阵从左上到右下。
这种解释可能仍然不清楚,请随时在注释中询问精度,我将编辑答案以更清楚。