Problem Description
Given an array of integers representing the values of stones arranged in a row, two players (Alice and Bob) take turns removing a number of stones from the left. On each turn the current player must remove more than one stone (i.e. choose an integer x > 1), add the sum of those removed stones to his/her score, and then place a new stone with that summed value at the beginning of the row. The game stops when only one stone remains. Both players play optimally: Alice maximizes the final difference (Alice’s score minus Bob’s score) and Bob minimizes it. Return the optimal score difference after all moves have been made.
Key Insights
- The game has an optimal substructure and can be solved using dynamic programming.
- Precompute the prefix sum array, where prefixSum[i] is the sum of the first (i+1) stones.
- Define a DP state such that dp[i] represents the maximum score difference that the current player can achieve given that the first (i+1) stones (from the original stones array) have been “formed” into one composite game state.
- The recurrence relation can be derived from the idea that from position i, a player can choose to remove stones so that his gain is prefixSum[i] and then the opponent will get dp[i+1]. Hence, the recurrence is: • dp[i] = max(prefixSum[i] - dp[i+1], dp[i+1])
- Note that the game is “forced” to start from index 1 (i.e. the first move by Alice always removes at least 2 stones) so the answer is dp[1].
- Reverse-order (backward) DP is used since the decision at each “state” depends on the state resulting from taking further moves.
Space and Time Complexity
Time Complexity: O(n) – We iterate over the stones array once to compute the prefix sum and then once more for the DP. Space Complexity: O(n) – Additional space is used for the prefix sum and DP arrays. (This can be optimized to O(1) if only the next DP value is stored.)
Solution
We first compute the prefix sum array for the original stones array. Let prefixSum[i] be the sum of stones from index 0 to i. Then we define a DP array where dp[i] represents the maximum score difference the current player can achieve when the game state is defined by the prefix sum up to index i. The recurrence is defined as:
dp[i] = max(prefixSum[i] - dp[i+1], dp[i+1])
for i from n-2 downto 1, and the base case is dp[n-1] = prefixSum[n-1] (i.e. when there are only two stones left to process a move). Finally, the answer is dp[1] because Alice’s first move must remove at least 2 stones.
The key trick is to realize that at every move, the player’s gain is the sum of the removed stones (obtained from the prefix sum) minus the optimal outcome for the opponent in the remaining state.