当前位置:   article > 正文

博弈论,LeetCode 1686. 石子游戏 VI

博弈论,LeetCode 1686. 石子游戏 VI

一、题目

1、题目描述

Alice 和 Bob 轮流玩一个游戏,Alice 先手。

一堆石子里总共有 n 个石子,轮到某个玩家时,他可以 移出 一个石子并得到这个石子的价值。Alice 和 Bob 对石子价值有 不一样的的评判标准 。双方都知道对方的评判标准。

给你两个长度为 n 的整数数组 aliceValues 和 bobValues 。aliceValues[i] 和 bobValues[i] 分别表示 Alice 和 Bob 认为第 i 个石子的价值。

所有石子都被取完后,得分较高的人为胜者。如果两个玩家得分相同,那么为平局。两位玩家都会采用 最优策略 进行游戏。

请你推断游戏的结果,用如下的方式表示:

  • 如果 Alice 赢,返回 1 。
  • 如果 Bob 赢,返回 -1 。
  • 如果游戏平局,返回 0 。

2、接口描述

  1. class Solution {
  2. public:
  3. int stoneGameVI(vector<int>& aliceValues, vector<int>& bobValues) {
  4. }
  5. };

3、原题链接

1686. 石子游戏 VI


二、解题报告

1、思路分析

这个题目其实还是蛮好考虑的,竞争者只有两个,赢家只有一个,设alice最终得分为s1,bob为s2

Alice要想赢得话,最终s1 > s2,正难则反

我们考虑Alice拿了第i1,i2,i3……件物品,那么Bob只能拿Alice拿剩下的

这个过程可以等效为,Bob初始就拿着所有的物品,Alice从Bob手中拿走了一部分物品

假如Alice先拿第i件,那么s1 += a[i] , s2 -= b[i],ds1 - ds2 = a[i] + b[i]

我们要让最终的s1 - s2尽可能大,那么每次ds1 - ds2就要尽可能大,a[i] + b[i]就要尽可能大

所以二者每次贪心的取a[i] + b[i]最大的即可

2、复杂度

时间复杂度: O(nlogn) 空间复杂度:O(n)

3、代码详解

  1. class Solution {
  2. public:
  3. int stoneGameVI(vector<int>& a, vector<int>& b) {
  4. int n = a.size(), diff = 0;
  5. vector<int> id(n);
  6. iota(id.begin(), id.end(), 0);
  7. sort(id.begin(), id.end(), [&](int x, int y){ return a[x] + b[x] > a[y] + b[y]; });
  8. for(int i = 0; i < n; i++)
  9. diff += (i & 1) ? -b[id[i]] : a[id[i]];
  10. return (diff > 0) - (diff < 0);
  11. }
  12. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/数据挖掘灵魂/article/detail/60461
推荐阅读
相关标签
  

闽ICP备14008679号