877. Stone Game
Jeff posted on (updated on )
Question: https://leetcode.com/problems/stone-game/
Post: https://leetcode.com/problems/stone-game/discuss/430915/java-single-dp-array-easier-to-understand
class Solution {
public boolean stoneGame(int[] piles) {
int N = piles.length;
if (N == 0) {
return true;
}
// True if dp[i][j] is already computed
boolean[][] flag = new boolean[N][N];
// dp[i][j] := Maximum stone Alice can pick given piles[i...j] (both inclusive)
int[][] dp = new int[N][N];
// init dp
// calculate sum
int sum = 0;
for (int i = 0; i < N; i++) {
dp[i][i] = piles[i];
sum += piles[i];
}
int ans = helper(0, N - 1, piles, flag, dp);
// You win if you have more than half of all the stones
return ans > (sum / 2);
}
int helper(int i, int j, int[] piles, boolean[][] flag, int[][] dp) {
if (i > j) {
return 0;
}
// memo
if (flag[i][j]) {
return dp[i][j];
}
// We take the minimal of two because Bob is going to pick optimially, leaving us minimal result
// Alice pick left
// Then Bob pick left
int left = piles[i] + Math.min(helper(i + 2, j, piles, flag, dp),
// bob pick right
helper(i + 1, j - 1, piles, flag, dp));
// Alice pick right
// Then Bob pick left
int right = piles[j] + Math.min(helper(i + 1, j - 1, piles, flag, dp),
// bob pick right
helper(i, j - 2, piles, flag, dp));
int best = Math.max(left, right);
dp[i][j] = best;
flag[i][j] = true;
return best;
}
}