我有2个问题来自一个简单的问题。我将用找到的解决方案来说明简单的解决方案,然后再介绍修改后的问题。
假设有一个有2个玩家的游戏,A和B,并且有一个 正整数。玩家A首先从列表中取出一个数字,玩家 B执行相同的操作,依此类推,之后的数字不再 清单。两位玩家将选择的数字相加。目标 对于每个玩家来说,就是要最大程度地提高他和 对手的总和,即得分。问题是什么是 如果两个玩家都以最佳状态玩游戏,则玩家A可以获得最高分数 方式。
现在,为此,我发现针对每个玩家的最佳策略是在每一步中取最大数字,伪代码如下:
sumA = 0
sumB = 0
list = [1, 5, 3, 7, 9]
while list IS NOT EMPTY:
val = pop_max(list)
sumA = sumA + val
if list IS NOT EMPTY:
val = pop_max(list)
sumB = sumB + val
scoreA = sumA - sumB
print scoreA
这可以在 O(n)或 O(n * log(n))中运行,具体取决于列表中数字的排序方式。
以下2个修改:
在游戏者开始时,A应该从列表中删除K个数字。如果他以最佳方式做到这一点,而在此之后是第一场比赛,那么他可以获得的最高分是多少?
和
在每个步骤中,玩家都可以从列表中选择最左边或最右边的数字。同样,它们以最佳方式发挥。玩家A可获得的最高分数是多少?
对于第二种修改,我可以想到一种蛮力方法,即计算所有可能性的树,但这不适用于大输入数据。我相信这里有某种DP算法。
对于第一个修改,我想不出一个主意。
有人可以对这两种修改提供一些算法建议吗?
[后期编辑]
第二个修改的解决方案可以在这里找到https://www.geeksforgeeks.org/optimal-strategy-for-a-game-dp-31/,它是DP。
答案 0 :(得分:0)
这是第二次修改的帖子,
在每个步骤中,玩家都可以从列表中选择最左边或最右边的数字。同样,它们以最佳方式发挥。玩家A可获得的最高分数是多少?
该解决方案基于DP。对于子问题(i-j),即v[]i, v[i+1], ..., v[j]
,有两种选择:
v[i] + min(F(i+2, j), F(i+1, j-1))
v[j] + min(F(i+1, j-1), F(i, j-2))
以下是基于上述两个选择的递归解决方案。我们最多选择两个。
F(i,j)表示用户可以从第i个硬币到第j个硬币收集的最大值。
F(i,j)= Max(v [i] + min(F(i + 2,j),F(i + 1,j-1)),v [j] + min(F(i +1,j-1),F(i,j-2)))
基本案例
F(i,j)= v [i]如果j == i
F(i,j)= max(v [i],v [j])如果j == i + 1
这是解决该问题的Python代码的一部分
def optimalStrategyOfGame(arr, n):
# Create a table to store solutions of subproblems
table = [[0 for i in range(n)] for i in range(n)]
# Fill table using above recursive formula. Note that the table is
# filled in diagonal fashion from diagonal elements to table[0][n-1] which is the result.
for gap in range(n):
for j in range(gap, n):
i = j - gap
# Here x is value of F(i+2, j), y is F(i+1, j-1) and z is
# F(i, j-2) in above recursive formula
x = 0
if((i + 2) <= j):
x = table[i + 2][j]
y = 0
if((i + 1) <= (j - 1)):
y = table[i + 1][j - 1]
z = 0
if(i <= (j - 2)):
z = table[i][j - 2]
table[i][j] = max(arr[i] + min(x, y), arr[j] + min(y, z))
return table[0][n - 1]
[源] https://www.geeksforgeeks.org/optimal-strategy-for-a-game-dp-31/