赞
踩
Alice 和 Bob 轮流玩一个游戏,Alice 先手。
一堆石子里总共有
n
个石子,轮到某个玩家时,他可以 移出 一个石子并得到这个石子的价值。Alice 和 Bob 对石子价值有 不一样的的评判标准 。双方都知道对方的评判标准。给你两个长度为
n
的整数数组aliceValues
和bobValues
。aliceValues[i]
和bobValues[i]
分别表示 Alice 和 Bob 认为第i
个石子的价值。所有石子都被取完后,得分较高的人为胜者。如果两个玩家得分相同,那么为平局。两位玩家都会采用 最优策略 进行游戏。
请你推断游戏的结果,用如下的方式表示:
- 如果 Alice 赢,返回
1
。- 如果 Bob 赢,返回
-1
。- 如果游戏平局,返回
0
。
- class Solution {
- public:
- int stoneGameVI(vector<int>& aliceValues, vector<int>& bobValues) {
-
- }
- };
这个题目其实还是蛮好考虑的,竞争者只有两个,赢家只有一个,设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]最大的即可
时间复杂度: O(nlogn) 空间复杂度:O(n)
- class Solution {
- public:
- int stoneGameVI(vector<int>& a, vector<int>& b) {
- int n = a.size(), diff = 0;
- vector<int> id(n);
- iota(id.begin(), id.end(), 0);
- sort(id.begin(), id.end(), [&](int x, int y){ return a[x] + b[x] > a[y] + b[y]; });
- for(int i = 0; i < n; i++)
- diff += (i & 1) ? -b[id[i]] : a[id[i]];
- return (diff > 0) - (diff < 0);
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。