你正在玩一个单人游戏,面前放置着大小分别为 a
、b
和 c
的 三堆 石子。
每回合你都要从两个 不同的非空堆 中取出一颗石子,并在得分上加 1
分。当存在 两个或更多 的空堆时,游戏停止。
给你三个整数 a
、b
和 c
,返回可以得到的 最大分数 。
示例 1:
输入:a = 2, b = 4, c = 6 输出:6 解释:石子起始状态是 (2, 4, 6) ,最优的一组操作是: - 从第一和第三堆取,石子状态现在是 (1, 4, 5) - 从第一和第三堆取,石子状态现在是 (0, 4, 4) - 从第二和第三堆取,石子状态现在是 (0, 3, 3) - 从第二和第三堆取,石子状态现在是 (0, 2, 2) - 从第二和第三堆取,石子状态现在是 (0, 1, 1) - 从第二和第三堆取,石子状态现在是 (0, 0, 0) 总分:6 分 。
示例 2:
输入:a = 4, b = 4, c = 6 输出:7 解释:石子起始状态是 (4, 4, 6) ,最优的一组操作是: - 从第一和第二堆取,石子状态现在是 (3, 3, 6) - 从第一和第三堆取,石子状态现在是 (2, 3, 5) - 从第一和第三堆取,石子状态现在是 (1, 3, 4) - 从第一和第三堆取,石子状态现在是 (0, 3, 3) - 从第二和第三堆取,石子状态现在是 (0, 2, 2) - 从第二和第三堆取,石子状态现在是 (0, 1, 1) - 从第二和第三堆取,石子状态现在是 (0, 0, 0) 总分:7 分 。
示例 3:
输入:a = 1, b = 8, c = 8 输出:8 解释:最优的一组操作是连续从第二和第三堆取 8 回合,直到将它们取空。 注意,由于第二和第三堆已经空了,游戏结束,不能继续从第一堆中取石子。
提示:
1 <= a, b, c <= 105
方法一:贪心 + 模拟
每次贪心地从最大的两堆石子中取石头,直到至少有两堆石子为空。
时间复杂度
方法二:贪心 + 数学
我们不妨设
- 当
$a + b \le c$ 时,我们可以先从$a$ ,$c$ 两堆中取石头,得到分数$a$ ;再从$b$ ,$c$ 两堆中取石头,得到分数$b$ ,总分数为$a + b$ ; - 当
$a + b \gt c$ 时,这时我们每次会从$c$ 以及$a$ 和$b$ 中较大的那一堆中取石头,最终将$c$ 取空。此时$a$ 和$b$ 的大小差最多为$1$ 。我们再从$a$ ,$b$ 两堆中取石头,直到不能取为止,总分数为$\left \lfloor \frac{a + b + c}{2} \right \rfloor$ 。
时间复杂度
class Solution:
def maximumScore(self, a: int, b: int, c: int) -> int:
s = sorted([a, b, c])
ans = 0
while s[1]:
ans += 1
s[1] -= 1
s[2] -= 1
s.sort()
return ans
class Solution:
def maximumScore(self, a: int, b: int, c: int) -> int:
a, b, c = sorted([a, b, c])
if a + b < c:
return a + b
return (a + b + c) >> 1
class Solution {
public int maximumScore(int a, int b, int c) {
int[] s = new int[] {a, b, c};
Arrays.sort(s);
int ans = 0;
while (s[1] > 0) {
++ans;
s[1]--;
s[2]--;
Arrays.sort(s);
}
return ans;
}
}
class Solution {
public int maximumScore(int a, int b, int c) {
int[] s = new int[] {a, b, c};
Arrays.sort(s);
if (s[0] + s[1] < s[2]) {
return s[0] + s[1];
}
return (a + b + c) >> 1;
}
}
class Solution {
public:
int maximumScore(int a, int b, int c) {
vector<int> s = {a, b, c};
sort(s.begin(), s.end());
int ans = 0;
while (s[1]) {
++ans;
s[1]--;
s[2]--;
sort(s.begin(), s.end());
}
return ans;
}
};
class Solution {
public:
int maximumScore(int a, int b, int c) {
vector<int> s = {a, b, c};
sort(s.begin(), s.end());
if (s[0] + s[1] < s[2]) return s[0] + s[1];
return (a + b + c) >> 1;
}
};
func maximumScore(a int, b int, c int) (ans int) {
s := []int{a, b, c}
sort.Ints(s)
for s[1] > 0 {
ans++
s[1]--
s[2]--
sort.Ints(s)
}
return
}
func maximumScore(a int, b int, c int) int {
s := []int{a, b, c}
sort.Ints(s)
if s[0]+s[1] < s[2] {
return s[0] + s[1]
}
return (a + b + c) >> 1
}