移除石子的最大得分
力扣 1753
现在有 \(3\) 堆石头 a、b、c,你必须从其中还有石头的两堆中各取出一颗不放回,并记录得分 +1。
如果出现两堆或者三堆都没有石头时,游戏结束。
请你求出所能得到的最大得分。
完善代码
数据范围
\(1 \leq\) a、b、c \(\leq 10 ^ 5\)
优先队列
不断消耗掉最大的两堆。
代码参考
class Solution {
public:
priority_queue<int> pq;
int res;
int maximumScore(int a, int b, int c) {
pq.push(a); pq.push(b); pq.push(c);
res = 0;
while (pq.size() > 1)
{
int x = pq.top(); pq.pop();
int y = pq.top(); pq.pop();
res += 1;
if (x - 1) pq.push(x - 1);
if (y - 1) pq.push(y - 1);
}
return res;
}
};
贪心
最优的结果是什么?当然是全部消耗为 \(0\)。
例如 [2, 2, 4] 最优的答案就是全部消耗为 \(0\) 得到 [0, 0, 0],得分为 4。
并不是所有的情况都能全部消耗为 \(0\),但是我们要尽可能的往全部都能消耗的方向考虑。
令 a <= b <= c,我们先将 a 和 b 降至相等:
a, b -= b - a, c -= b - a, res = b - a
如果要全部消耗为 \(0\),那么最终 a、b 也会为 \(0\),我们先想办法消耗掉 c,
如果 2 * a <= c,说明 c 一定有剩,并且此时的最优值就是将 a、b 与 c 对消:
a -= a, b -= b, c -= a + b, res = a + b
如果 2 * a > c,就先将 c 分成均等的两部分:c / 2,a 和 b 都要对消掉 c / 2:
a -= c / 2, b -= c / 2, c %= 2, res += c / 2 * 2
接下来就可以同时对消 a 和 b,让 a 和 b 同时为 \(0\):
a -= a, b -= b, c, res += a
此时最多就会剩下 \(1\) 个,归纳公式为 :
res += c / 2 * 2 + a - c / 2
res += a + c / 2