我有以下任务要解决:
两个玩家玩游戏。在这个游戏中有硬币,每个硬币都有一个值。每个玩家轮流选择1个硬币。目标是最终获得最高的总价值。每个玩家都必须选择玩(这意味着始终从堆中选择最高值)。我必须找出2位玩家的总和/他们最高的总和之间的差额
约束:所有值均为自然整数且为正。
上面的任务是一个经典的贪婪问题。根据我的尝试,可以使用quickSort对其进行排序,然后只为2个玩家选择元素。如果您在测试中需要更好的时间,则Radix-Sort的性能会更好。好了,这个任务很简单。
现在我的任务与上述相同,但第一个玩家必须删除OPTIMALLY K个硬币,以使它们的得分之间的差异最大。听起来像DP,但我无法解决。我必须再次找出他们的得分之间的最大差额(两名球员均处于最佳状态)。或者说,这两个玩家的得分之间的差异最大。
是否已经实施了这样的算法?或者有人可以给我一些有关此问题的提示吗?
答案 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}}矩阵从左上到右下。
这种解释可能仍然不清楚,请随时在注释中询问精度,我将编辑答案以更清楚。