文章目录
题目描述
Alice 和 Bob 轮流玩一个游戏,Alice 先手。
一堆石子里总共有n
个石子,轮到某个玩家时,他可以 移出 一个石子并得到这个石子的价值。Alice 和 Bob 对石子价值有 不一样的的评判标准 。双方都知道对方的评判标准。
给你两个长度为n
的整数数组aliceValues
和bobValues
。aliceValues[i]
和bobValues[i]
分别表示Alice
和Bob
认为第i
个石子的价值。
所有石子都被取完后,得分较高的人为胜者。如果两个玩家得分相同,那么为平局。两位玩家都会采用 最优策略 进行游戏。
请你推断游戏的结果,用如下的方式表示:
- 如果 Alice 赢,返回 1 。
- 如果 Bob 赢,返回 -1 。
- 如果游戏平局,返回 0 。
问题分析
假设 Alice 选择石子i
,Bob 选择石子j
,则 Alice 与 Bob 之间的石子价值差为aliceValues[i] - bobValues[j]
;若 Alice 选择石子j
,Bob 选择石子i
,则 Alice 与 Bob 之间的石子价值差为aliceValues[j] - bobValues[i]
对比两种方案的优劣,可以对这两种方案的价值做差,即aliceValues[i] - bobValues[j] - (aliceValues[j] - bobValues[i]) = (aliceValues[i] + bobValues[i]) - (aliceValues[j] + bobValues[j])
。即 Alice 和 Bob 采用的最优策略都是先选择aliceValues[i] + bobValues[i]
值最大的。
因此,对aliceValues[i] + bobValues[i]
值从大到小进行排序, Alice 和 Bob 依次选择,就是最终的结果。
程序代码
go
func stoneGameVI(aliceValues []int, bobValues []int) int {
n := len(aliceValues)
choices := make([][]int, n)
for i := 0; i < n; i++ {
choices[i] = []int{aliceValues[i] + bobValues[i], aliceValues[i]}
}
sort.Slice(choices, func(i, j int) bool {
return choices[i][0] > choices[j][0]
})
aSum, bSum := 0, 0
for i := 0; i < n; i++ {
if i % 2 == 0 {
aSum += choices[i][1]
} else {
bSum += choices[i][0] - choices[i][1]
}
}
if aSum > bSum {
return 1
} else if aSum == bSum {
return 0
} else {
return -1
}
}