如何在此游戏中最大化总和?

时间:2015-09-12 11:32:21

标签: arrays algorithm

所以,我在接受采访时被问到这个问题:

有两个朋友正在玩游戏,他们从包含n正数的数组中选择一个数字。两个朋友一次选择一个号码,并且两个玩家都以最佳方式玩游戏。而且你必须找出游戏结束后你可以获得的最大总和(被选中的数字)。在我无限制地给出相同问题的答案之后给出的约束是:

  1. 在两位球员的第一步中,他们可以选择任何数字。
  2. 除了第一次移动之外,他们只能选择与给定阵列中的前一个数字相邻的数字,并且直到游戏中的那个时刻,第一个和第二个玩家都没有选择该数字。 (澄清为编辑)
  3. 如果玩家无法移动,他/她就会停止游戏。当两位球员都无法采取行动时,比赛结束。

    现在,我给出的解决方案是:

    1. 创建一个包含值以及输入数组中值的索引的结构。
    2. 创建上一个结构的数组,并将第一步的值存储在此数组中。
    3. 根据值以非递减顺序对此数组进行排序。
    4. 开始以贪婪的方式选择一个值并打印最大值。
    5. 虽然我也可以编写代码,但他们正在寻找伪代码。但是,采访者说在某些情况下会失败。我想了很多关于哪些情况会失败但却找不到。因此,我在这个问题上需要帮助。

      另外,如果可能的话,请提供一个伪代码,说明我可以做些什么来改善这一点。

      编辑:我想我的问题不够清楚,特别是在第二点。采访者的意思是:

      如果不是玩家的第一步,他必须选择一个与之前移动中已选择的数字相邻的数字。

      另外,是的,两位玩家都以最佳方式玩游戏并且他们选择轮流转动数字。

      Edit2:所以,我的朋友问了同样的问题但是它被修改了一点。而不是数组,他给出的是一个图表。所以,就像在我的情况下,我只能选择与我之前选择的索引相邻的索引,他给出的是一个无向图(邻接列表作为输入),他只能选择特定移动中直接的那些顶点连接到任何先前选择的顶点。

      例如: 假设正整数的数量是3.这些整数的值是424,如果我用A命名正整数,{ {1}}和B,然后,

      C

      上面是我的朋友给出的例子,上面的答案是A - B B - C 。你能指出我如何从这个开始的正确方向吗?谢谢!

4 个答案:

答案 0 :(得分:3)

请注意,如果您在索引x进行第一次移动,如果您的对手以最佳状态进行游戏,则他们的第一步移动必须是索引x-1x+1。否则,他们将拥有他们可以选择但没有选择的元素。要看到这一点,请考虑两个不相邻的起点:

-------y-------------x-------

最终,他们都会从数组中获取元素并最终得到类似的内容:

yyyyyyyyyyyyyyxxxxxxxxxxxxxxx

因此,您可以将起点重新定位到中间yx,从而获得相同的解决方案。

所以,假设你先在x移动。让:

s_left_x = a[0] + ... + a[x]
s_right_x = a[x] + ... a[n - 1]

s_left_y = a[0] + ... + a[x - 1]
s_right_y = a[x + 1] + ... + a[n - 1]

假设您想要赢得比赛:最后获得比对手更大的金额。如果对手选择x + 1,则需要s_left_x > s_right_y,如果对手选择x - 1,则需要s_right_x > s_left_y。理想情况下,这是为了获胜。虽然赢得并不总是可能的,但你的问题不是要求如何获胜,而是如何获得最大的金额。

由于你的对手会发挥最佳状态,他会迫使你进入最糟糕的情况。因此,对于每个x作为您的第一步,您可以做的最好的是min(s_left_x, s_right_x)。为每个索引x选择此表达式的最大值,在一些预先计算后,您可以在O(1)中找到每个索引的索引。

答案 1 :(得分:1)

好的,我认为这是解决方案,更简单地制定了:

第一个玩家必须选择将数组一分为二的项目,两个结果数组的总和差异小于拾取项目的值。

如果可以实现,p1获胜,如果没有,p2获胜。

显然,在第一次移动时,p2必须选择p1旁边的项目,因为这是他获得最大金额的唯一方法。他选择旁边的项目,其余的项目总和更大。这将是p2可以获得的最大总和。

p1的最大总和将是剩余项目的总和(项目在侧面,p2未选择加上第一步中选择的项目p1。)

答案 2 :(得分:1)

由于OP提到双方都以最佳方式玩游戏,我将在此假设下提出算法。

当然,如果两位球员都达到最佳状态,那么他们最终得到的总和肯定会达到最大值,否则就无法达到最佳状态。

这里有两种不同的情况:

我在位置x进行第一次移动和拾取元素

现在因为我们必须遵守只能挑选相邻元素的条件,让我在这里定义两个数组。

left [x]:它是可以通过添加

获得的元素之和
array[0],array[1]....array[x-1],the elements left to x.

right [x]:它是可以通过添加

获得的元素之和
array[x+1],array[x+2]....array[n-1],the elements right to x.

现在,因为其他玩家也玩得最好,他会做的是他会检查我可以实现的目标,他发现,我可以达到以下目的:

array[x] + left[x] = S1

array[x] + right[x] = S2

所以其他玩家所做的就是找到S1和S2的最小值。

如果S1< S2这意味着如果另一个玩家在x + 1处选择元素,他就会从我们这里拿走阵列中更好的部分,因为现在我们留下了较少的数额S1

如果S1> S2这意味着如果其他玩家在x-1处选择元素,他就会从我们这里拿走阵列中更好的部分,因为现在我们留下的是较少的总和S2

因为我也玩得最好所以我会在第一步中选择这样的x,其最小绝对值为(右[x] -left [x]),这样即使我们的对手得到了更好的部分来自我们的阵列,他只能拿走最低

因此,如果两个玩家都达到最佳状态,则获得的最大金额为:

<强>更新

x + left[x]  and right[x]//when second player in his first move picks x+1

因此,在这种情况下,所做的动作是:

Player 1:Picks element at position x,x-1,x-2....0.

Player 2:Picks element at position x+1,x+2,....n-1

因为每个玩家必须选择相邻元素到他之前挑选的元素。

x + right[x] and left[x]//when second player in his first move picks x-1

因此,在这种情况下,所做的动作是:

Player 1:Picks element at position x,x+1,x+2....n-1.

Player 2:Picks element at position x-1,x-2,....0.

因为每个玩家必须选择相邻元素到他之前挑选的元素。

其中x是我们获得(right [x] -left [x])的最小绝对值。

由于OP坚持发布伪代码,这里有一个:

计算左右数组。

for(i = 0 to n-1)
{
 if(i==0)
  left[i]=0;
 else left[i] = left[i] + array[i-1];

 j = n-1-i;
 if(j==n-1)
  right[j]=0;
 else right[j]= right[j] + array[j+1];
}

左右数组在所有位置最初都为0。

计算max_sums。

Find_the_max_sums()
{
 min = absoulte_value_of(right[0]-left[0])
 x = 0;
 for(i = 1 to n-1)
 {
  if( absolute_value_of(right[i]-left[i]) < min)
  {
   min = absolute_value_of(right[i]-left[i]); 
   x=i;
  }
 }
}

显然,该算法的空间和时间复杂度都是线性的。

答案 3 :(得分:0)

在给定限制的情况下,任何游戏中的最大总和始终是从给定的拆分位置S到位置1或位置N的多个相邻值的加法。玩家1选择初始拆分点S和玩家2选择要加和的数组边(因此,玩家2也选择玩家1的边)。一个玩家将从1(或S-1)加1,另一个将S(或S + 1)加至N。

为了赢得比赛,玩家1必须找到一个分割位置S,使得从1到S-1和从S + 1到N的加法严格小于另一方的和加S的值这样,无论播放器2选择向哪一侧添加,其总和都会较小。

伪代码:

1. For each position S from 1 to N, repeat:
1.1. Add values from 1 to S-1 (set to zero if S is 1), assign to S1.
1.2. Add values from S+1 to N (set to zero if S is N), assign to SN.
1.3. If S1 is smaller than S+SN and SN is smaller than S+S1, then S is the winning position for Player 1. If not, repeat.
2. If you have found no winning position, then whatever you choose Player 2 can win choosing in turn an optimal position.