Algorithm 最优移除K个硬币后选择最大数量的游戏

Algorithm 最优移除K个硬币后选择最大数量的游戏,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我有以下任务要解决: 两个玩家玩一个游戏。在这个游戏中有硬币,每个硬币都有一个值。每位玩家轮流选择一枚硬币。目标是最终获得最高的总价值。每个玩家都被强制选择玩(这意味着总是从堆中选择最高的值)。我必须找出这两位选手的总和/他们可能的最高总和之间的差额 约束:所有值都是自然整数和正整数 上面的任务是一个典型的贪婪问题。根据我的尝试,它可以通过快速排序进行排序,然后根据2名玩家的顺序选择元素。如果你需要在我的测试中有更好的时间,基数排序的性能会更好。好的,这个任务很简单 现在我有和上面相同的任务,但

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

约束:所有值都是自然整数和正整数

上面的任务是一个典型的贪婪问题。根据我的尝试,它可以通过快速排序进行排序,然后根据2名玩家的顺序选择元素。如果你需要在我的测试中有更好的时间,基数排序的性能会更好。好的,这个任务很简单

现在我有和上面相同的任务,但是第一个玩家必须移除最佳的K个硬币,这样他们的分数之间的差异是最大的。好吧,这听起来像DP,但我想不出解决办法。我必须再次找出他们得分之间的最大差异(两名球员都打得很好)。或者两名球员的积分差距最大


是否已经实现了这样的算法?或者有人能给我一些关于这个问题的建议吗

这里是一个DP方法解决方案。我们考虑<代码> n <代码>硬币,按降序排序简化符号(意思是代码>硬币[0 ] < /代码>是最高值硬币,而<代码>硬币[N-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])
这种重复仅仅意味着,在任何时候,最佳选择是移除硬币(在最佳值为
M(i,j-1)
的情况下),还是不移除它(在最佳值为
M(i-1,j)+/-coins[i+j]
的情况下)。
这将给你最终的分数差,但不是要移除的硬币集。要找到它,您必须保留程序用于计算矩阵值的“最佳路径”(最佳值是来自M(i-1,j)还是来自M(i,j-1)?。
此路径可以为您提供要查找的集合。顺便说一句,你可以看到这是有道理的,因为在n中有
k个
k个
n
硬币中移除
k个
k个
k个
k个
k个
k个
n-k
硬币的可能方法,如果你只允许向右或向下移动的话。

这个解释可能仍然不清楚,请不要犹豫,询问评论中的精确性,我将编辑答案以使其更清晰。

我不太理解规则,您能提供一个简单的示例吗?当然,假设我们有值:9 7和2。第一个玩家必须消除1枚硬币,以最大限度地扩大他们之间的分数差异。因此,第一个玩家决定消除价值为7的硬币。他选择了价值为9的硬币,而另一个玩家只剩下一枚价值为2的硬币->他们的总和之差为7@m.raynal你说得对,我解释得不好。我应该提到,你必须以这样一种方式移除K币,即分数之间的差异最大。因此,这意味着在“正常”游戏(你描述的第一条规则)中,玩家必须首先从游戏中移除一枚硬币,然后必须选择另一枚硬币。因此,最终在这个版本中,每回合后游戏中少2枚硬币,贪婪的方法是为自己选择价值最高的硬币,并消除第二高价值的硬币,以防止对手使用它。我说得对吗?@m.raynal No.在正常游戏中,你只有硬币,每个玩家都必须选择要保留的硬币(最后我们总结硬币的价值,看看谁有更多,所以每个玩家都必须选择场上价值最高的硬币)。在第二种变体中,第一个玩家必须首先从游戏中移除k个硬币。然后游戏开始。(必须以这样一种方式移除k币,即第一名玩家和第二名玩家的分数之间的差异最大,两名玩家都要赢,因此选择可能的最高金额的硬币)。事实上,对我来说,这很有意义。我没有想到:M(I,j)=max(M(I,j-1),M(I-1,j)+硬币[I+j])。那个麦克斯的东西。然而,如果我在实施过程中不能理解某些东西,我会在不久的将来问更多的问题。但这是正确的答案,所以我会这样做。哦@m、 根据我的理解,我在m(n-k,k)中得到的,实际上是玩家一可能得到的最高总和。但是我也需要玩家2的总和。我的答案必须是玩家1和玩家2的得分之间的最大差值。这是我必须弄清楚的。因此,我的矩阵必须包含两个分数,或者每个值必须是两个玩家分数之间的最大差值。我必须选择最大的一个。这有意义吗?存储的值实际上是差异,因为当一个玩家在玩时(当
i%2=0
时),我们添加的值