class Solution { private int[] getSuffixSum(int[] piles) { var suffix = new int[piles.length + 1]; for (int i = piles.length - 1; i >= 0; --i) { suffix[i] = suffix[i + 1] + piles[i]; } return suffix; } private void compute(int n, int[] suffix, int[][] dp, int i) { var row = dp[i]; for (int maxAllowed = n - 1; maxAllowed >= 1; --maxAllowed) { for (int x = 1; x <= 2 * maxAllowed && i + x <= n; ++x) { row[maxAllowed] = Math.max(row[maxAllowed], suffix[i] - dp[i + x][Math.max(maxAllowed, x)]); } } } public int stoneGameII(int[] piles) { int n = piles.length; var suffix = getSuffixSum(piles); var dp = new int[n + 1][n + 1]; // Handle base case. for (int i = 0; i <= n; ++i) { dp[i][n] = suffix[i]; } for (int i = n - 1; i >= 0; --i) { compute(n, suffix, dp, i); } return dp[0][1]; } }