题目:
有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币:
- 每一轮中,你将会选出 任意 3 堆硬币(不一定连续)。
- Alice 将会取走硬币数量最多的那一堆。
- 你将会取走硬币数量第二多的那一堆。
- Bob 将会取走最后一堆。
- 重复这个过程,直到没有更多硬币。
给你一个整数数组 piles
,其中 piles[i]
是第 i
堆中硬币的数目。
返回你可以获得的最大硬币数目。
示例 1:
输入:piles = [2,4,1,2,7,8]
输出:9
解释:选出 (2, 7, 8) ,Alice 取走 8 枚硬币的那堆,你取走 7 枚硬币的那堆,Bob 取走最后一堆。
选出 (1, 2, 4) , Alice 取走 4 枚硬币的那堆,你取走 2 枚硬币的那堆,Bob 取走最后一堆。
你可以获得的最大硬币数目:7 + 2 = 9.
考虑另外一种情况,如果选出的是 (1, 2, 8) 和 (2, 4, 7) ,你就只能得到 2 + 4 = 6 枚硬币,这不是最优解。
示例 2:
输入:piles = [2,4,5]
输出:4
示例 3:
输入:piles = [9,8,7,6,5,1,2,3,4]
输出:18
提示:
3 <= piles.length <= 10^5
piles.length % 3 == 0
1 <= piles[i] <= 10^4
思路:
问题相当于每次选三堆硬币,Alice 先取一堆,我们再取一堆,Bob 取剩下的那一堆。
由于 Bob 总是最后取,每一轮,我们可以把(剩余硬币堆中的)最少的那一堆硬币给 Bob。
由于 Alice 总是先取,那么我们不可能取到 piles 的最大值,但可以取到次大值。同理,第三大的给 Alice,我们取第四大的。依此类推。
因此,把 piles 从大到小排序后,我们可以取走下标为
1,3,5,…,2m−3,2m−1 的硬币堆,其中 m=n/3。(注意题目保证 n 是 3 的倍数)
也可以把 piles 从小到大排序,取走下标为 m,m+2,m+4,…,n−4,n−2 的硬币堆。
代码:
class Solution {
public:
int maxCoins(vector<int>& piles) {
ranges::sort(piles);
int n = piles.size();
int ans = 0;
for (int i = n / 3; i < n; i += 2) {
ans += piles[i];
}
return ans;
}
};