DP SOLUTION W/O TURN TRACKING || EASY TO UNDERSTAND
At first glance this solution might look like we are just returning the max score by which Alice will win, \nHere Bob will follow the approach to maximise diffe
At first glance this solution might look like we are just returning the max score by which Alice will win, \nHere Bob will follow the approach to maximise difference at his play so he will then minimize Alice\'s score when she picked the stone before his turn.\nalicePreviousPickDiff = optimalPickByAlice - bobNextPickDiff\nHere to minimize alicePreviousPickDiff, bob has to maximize bobNextPickDiff.\nSo it results in a solution resembling, JUMP GAME 1\n\nEdit: Better explanation by [@fallenranger](http://https://leetcode.com/fallenranger/)\nBob is maximizing the difference on his turn, and since this is negated on a layer above, overall Bob is playing the optimal move to minimize the difference.\nAlice - (Bob - (Alice - Bob))\nBy selecting max between two options, Bob is doing it\'s best to minimize the above difference.\n\n```\nclass Solution {\n    int dp[][];\n    public int stoneGameVII(int[] stones) {\n        dp = new int[stones.length][stones.length];\n        return score(stones, 0, stones.length - 1, Arrays.stream(stones).sum());\n    }\n    int score(int[] stones, int l, int r, int sum) {\n        if(l + 1 == r) return Math.max(stones[l], stones[r]);\n        if(dp[l][r] != 0) return dp[l][r];\n        int left = score(stones, l + 1, r, sum - stones[l]);\n        int right = score(stones, l, r - 1, sum - stones[r]);\n        dp[l][r] = Math.max(sum - stones[l] - left, sum - stones[r] - right);\n        return dp[l][r];\n    }\n}\n\n```
['Dynamic Programming', 'Java']