06. Optimal Strategy For A Game
β GFG solution to the Optimal Strategy For A Game problem: find maximum amount of money you can win if you go first, assuming both players play optimally. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given an integer array arr[] of size n (even). The array elements represent n coins of values v1, v2, ..., vn. You play against an opponent in an alternating way. In each turn, a player selects either the first or last coin from the row, removes it from the row permanently, and receives the coin's value.
You need to determine the maximum possible amount of money you can win if you go first.
Note: Both the players are playing optimally.
π Examples
Example 1
Input: arr[] = [5, 3, 7, 10]
Output: 15
Explanation: The user collects the maximum value as 15(10 + 5). It is guaranteed that we cannot get more than 15 by any possible moves.Example 2
Input: arr[] = [8, 15, 3, 7]
Output: 22
Explanation: The user collects the maximum value as 22(7 + 15). It is guaranteed that we cannot get more than 22 by any possible moves.π Constraints
$2 \le n \le 10^3$
$1 \le arr[i] \le 10^6$
β
My Approach
The optimal approach uses Dynamic Programming to efficiently compute the maximum amount the first player can win:
1D DP Optimized Approach
Understanding the Game:
Each player can choose either the first or last coin in their turn.
Both players play optimally, meaning they will always make the move that maximizes their own total.
We need to find the maximum amount the first player can collect.
DP State Definition:
Let
dp[i][j]represent the maximum advantage the current player can get over the opponent for the subarrayarr[i...j].This is the difference between the current player's total and the opponent's total for this subarray.
Recurrence Relation:
If the current player picks
arr[i], the opponent will then play optimally on the remaining subarrayarr[i+1...j]. The current player's advantage would bearr[i] - dp[i+1][j].If the current player picks
arr[j], the opponent will then play optimally on the remaining subarrayarr[i...j-1]. The current player's advantage would bearr[j] - dp[i][j-1].Therefore,
dp[i][j] = max(arr[i] - dp[i+1][j], arr[j] - dp[i][j-1]).
Optimization to 1D:
Instead of using a 2D table, we can optimize space by using a 1D array.
We process the array from right to left, updating our DP values for each starting index.
Calculating the Result:
Let
sumbe the total sum of all coin values.The maximum amount the first player can collect is
(sum + dp[0][n-1]) / 2.This is because
dp[0][n-1]represents the difference between the first player's total and the second player's total.If
first + second = sumandfirst - second = dp[0][n-1], thenfirst = (sum + dp[0][n-1]) / 2.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(nΒ²), where n is the size of the array. We need to fill a DP table for all possible subarrays.
Expected Auxiliary Space Complexity: O(n), as we only use a single array of size n to store intermediate DP values.
βοΈ Code (C)
π§βπ» Code (C++)
β‘ View Alternative Approaches with Code and Analysis
π 2οΈβ£ 2D DP Table Approach
π‘ Algorithm Steps:
Create a 2D DP table where
dp[i][j]represents max advantage for subarray [i,j].Fill diagonals first (single elements) then expand to larger subarrays.
At each step, player picks either first or last element optimally.
Calculate final amount by adding half of total sum and advantage.
π Complexity Analysis:
Time: β±οΈ O(nΒ²) - Fill all cells in 2D table
Auxiliary Space: πΎ O(nΒ²) - 2D DP table storage
β
Why This Approach?
Intuitive visualization of subproblems
Clear recursive structure with memoization
Easy to trace and debug intermediate states
π 3οΈβ£ Recursive Memoization
π‘ Algorithm Steps:
Define recursive function for range [left, right] representing current game state.
Base case when left equals right, return that element value.
Recursively explore picking from left or right end optimally.
Memoize results to avoid recomputing same subproblems.
π Complexity Analysis:
Time: β±οΈ O(nΒ²) - Each subproblem computed once
Auxiliary Space: πΎ O(nΒ²) - Memoization map and recursion stack
β
Why This Approach?
Top-down approach mirrors natural problem thinking
Easier to convert from brute force solution
Good for understanding problem structure
Note: This approach results in Time Limit Exceeded (TLE) for large inputs (fails ~1010/1115 test cases due to time constraints).
π 4οΈβ£ Space Optimized Rolling Array
π‘ Algorithm Steps:
Optimize space by maintaining only current and previous row of DP.
Process diagonally from bottom-right to top-left of conceptual table.
Update single array by reusing previously computed values.
Reduce space from O(nΒ²) to O(n) while maintaining correctness.
π Complexity Analysis:
Time: β±οΈ O(nΒ²) - Same computation as 2D approach
Auxiliary Space: πΎ O(n) - Only two arrays of size n
β
Why This Approach?
Significant space optimization over 2D DP
Maintains optimal time complexity
Better cache performance with smaller memory footprint
π π Comparison of Approaches
π Approach
β±οΈ Time Complexity
πΎ Space Complexity
β Pros
β οΈ Cons
π― 1D DP Optimized
π’ O(nΒ²)
π’ O(n)
π Best space efficiency
π§ Less intuitive logic
π 2D DP Table
π’ O(nΒ²)
π‘ O(nΒ²)
π Clear visualization
πΎ High memory usage
π Recursive Memo
π’ O(nΒ²)
π‘ O(nΒ²)
π― Natural problem structure
π Recursion overhead
β‘ Rolling Array
π’ O(nΒ²)
π’ O(n)
β Space optimized
π§ Moderate implementation complexity
π Best Choice Recommendation
π― Scenario
ποΈ Recommended Approach
π₯ Performance Rating
π Production/Memory constrained
π₯ 1D DP Optimized
β β β β β
π Learning/Understanding
π₯ 2D DP Table
β β β β β
π§ Prototyping/Quick solution
π₯ Recursive Memo
β β β β β
β‘ Balance of clarity & efficiency
π Rolling Array
β β β β β
β Code (Java)
π Code (Python)
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated