Welcome to Subscribe On Youtube
1753. Maximum Score From Removing Stones
Description
You are playing a solitaire game with three piles of stones of sizes a, b, and c respectively. Each turn you choose two different non-empty piles, take one stone from each, and add 1 point to your score. The game stops when there are fewer than two non-empty piles (meaning there are no more available moves).
Given three integers a, b, and c, return the maximum score you can get.
Example 1:
Input: a = 2, b = 4, c = 6 Output: 6 Explanation: The starting state is (2, 4, 6). One optimal set of moves is: - Take from 1st and 3rd piles, state is now (1, 4, 5) - Take from 1st and 3rd piles, state is now (0, 4, 4) - Take from 2nd and 3rd piles, state is now (0, 3, 3) - Take from 2nd and 3rd piles, state is now (0, 2, 2) - Take from 2nd and 3rd piles, state is now (0, 1, 1) - Take from 2nd and 3rd piles, state is now (0, 0, 0) There are fewer than two non-empty piles, so the game ends. Total: 6 points.
Example 2:
Input: a = 4, b = 4, c = 6 Output: 7 Explanation: The starting state is (4, 4, 6). One optimal set of moves is: - Take from 1st and 2nd piles, state is now (3, 3, 6) - Take from 1st and 3rd piles, state is now (2, 3, 5) - Take from 1st and 3rd piles, state is now (1, 3, 4) - Take from 1st and 3rd piles, state is now (0, 3, 3) - Take from 2nd and 3rd piles, state is now (0, 2, 2) - Take from 2nd and 3rd piles, state is now (0, 1, 1) - Take from 2nd and 3rd piles, state is now (0, 0, 0) There are fewer than two non-empty piles, so the game ends. Total: 7 points.
Example 3:
Input: a = 1, b = 8, c = 8 Output: 8 Explanation: One optimal set of moves is to take from the 2nd and 3rd piles for 8 turns until they are empty. After that, there are fewer than two non-empty piles, so the game ends.
Constraints:
1 <= a, b, c <= 105
Solutions
Solution 1: Sorting
Greedily take stones from the two largest piles of stones each time until at least two piles of stones are empty.
The time complexity is $O(n)$, where $n$ is the total number of stones.
Solution 2
We might as well set $a \le b \le c$, then:
- When $a + b \le c$, we can first take stones from the two piles $a$ and $c$ to get the score $a$; then take stones from the two piles $b$ and $c$ to get the score $b$, and the total score is $a + b$;
- When $a + b \gt c$, then we will take stones from the larger pile of $c$ and $a$ and $b$ each time, and eventually $c$ will be empty. At this time, the size difference between $a$ and $b$ is at most $1$. We then take stones from the two piles $a$ and $b$ until we can no longer take them. The total score is $\left \lfloor \frac{a + b + c}{2} \right \rfloor$.
Time complexity $O(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; } } // Solution 2 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; } }; // Solution 2 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; } }; -
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 # Solution 2 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 -
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 } // Solution 2 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 }