Coins in a Line

There are A coins (Assume A is even) in a line.

Two players take turns to take a coin from one of the ends of the line until there are no more coins left.

The player with the larger amount of money wins.

Assume that you go first.

Return the maximum amount of money you can win.

Input Format:

The first and the only argument of input contains an integer array, A.

Output Format:

Return an integer representing the maximum amount of money you can win.

Constraints:

1 <= length(A) <= 500
1 <= A[i] <= 1e5

Examples:

Input 1:
    A = [1, 2, 3, 4]

Output 1:
    6

Explanation 1:
    
    You      : Pick 4
    Opponent : Pick 3
    You      : Pick 2
    Opponent : Pick 1
    
    Total money with you : 4 + 2 = 6

Input 2:
    A = [5, 4, 8, 10]
    
Output 2:
    15

Explanation 2:

    You      : Pick 10
    Opponent : Pick 8
    You      : Pick 5
    Opponent : Pick 4
    
    Total money with you : 10 + 5 = 15
Solution:

Time: O(n^2)
Space: O(n^2)

public class Solution {
    public int maxcoin(int[] A) {
        // dp[i][j] = max coins a player can get from ith element to jth
        // dp[i][j] = max(
        //                A[i - 1] + min(dp[i + 2, j], dp[i + 1][j - 1]),
        //                A[j - 1] + min(dp[i + 1][j - 1], dp[i][j - 2]))
        //               )
        // dp[i][i] = A[i - 1], dp[i][i + 1] = max(A[i - 1], A[i])
        // dp[1][n]
        
        int n = A.length;
        int[][] dp = new int[n + 1][n + 1];
        for (int len = 0; len < n; len ++) {
            for (int i = 1; i <= n; i ++) {
                int j = i + len;
                if (i == j) {
                    dp[i][j] = A[i - 1]; 
                } else if (j <= n && j - i == 1) {
                    dp[i][j] = Math.max(A[i - 1], A[i]);
                } else if (j <= n) {
                    dp[i][j] = Math.max(
                        A[i - 1] + Math.min(dp[i + 2][j], dp[i + 1][j - 1]),
                        A[j - 1] + Math.min(dp[i + 1][j - 1], dp[i][j - 2])
                    );
                }
            }
        }
        // for (int[] a : dp) {
        //     System.out.println(Arrays.toString(a));
        // }
        return dp[1][n];
    }
}