最大化2位玩家的被选号码之和的差额

时间:2019-04-03 11:23:10

标签: algorithm dynamic-programming pseudocode greedy

我有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。

1 个答案:

答案 0 :(得分:0)

这是第二次修改的帖子,

  

在每个步骤中,玩家都可以从列表中选择最左边或最右边的数字。同样,它们以最佳方式发挥。玩家A可获得的最高分数是多少?

该解决方案基于DP。对于子问题(i-j),即v[]i, v[i+1], ..., v[j],有两种选择:

  1. 用户选择值为v [i]的第i个元素:对手选择第(i + 1)个元素或第j个元素。对手打算选择给用户留下最小值的元素。即用户可以收集值v[i] + min(F(i+2, j), F(i+1, j-1))

enter image description here

  1. 用户选择值为v [j]的第j个元素:对手选择第i个元素或第(j-1)个元素。对手打算选择给用户留下最小值的元素。 即用户可以收集值v[j] + min(F(i+1, j-1), F(i, j-2))

enter image description here

以下是基于上述两个选择的递归解决方案。我们最多选择两个。

  

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/