The best explanation by far is from the video. Thanks for sharing! Here's a Python translation:

```
class Solution(object):
def PredictTheWinner(self, nums):
def helper(v, dp, i, j):
if i > j:
return 0
if dp[i][j] != -1:
return dp[i][j]
a = v[i] + min(helper(v,dp,i+1, j-1), helper(v, dp, i+2,j))
b = v[j] + min(helper(v,dp,i,j-2), helper(v,dp,i+1, j-1))
dp[i][j] = max(a,b)
return dp[i][j]
if len(nums) % 2 == 0:
return True
n = len(nums)
dp = [[-1] * n for _ in xrange(n)]
myBest = helper(nums, dp, 0, n-1)
return 2*myBest >= sum(nums)
```

Java version:

```
import java.util.stream.*;
public class Solution {
public boolean PredictTheWinner(int[] nums) {
if(nums.length % 2 == 0) return true;
int n = nums.length;
int[][] dp = new int[n][n];
for(int i = 0; i < dp.length; i++)
Arrays.fill(dp[i], -1);
int myBest = utill(nums, dp, 0, n-1);
return 2*myBest >= IntStream.of(nums).sum();
}
public int utill(int[] v, int[][] dp, int i, int j){
if(i > j) return 0;
if(dp[i][j] != -1) return dp[i][j];
int a = v[i] + Math.min(utill(v,dp, i+1, j-1), utill(v, dp, i+2, j));
int b = v[j] + Math.min(utill(v,dp,i, j-2), utill(v,dp, i+1, j-1));
dp[i][j] = Math.max(a, b);
return dp[i][j];
}
}
```

Javascript:

```
var PredictTheWinner = function(nums) {
if(nums.length % 2 == 0) return true;
var n = nums.length;
var dp = new Array(n);
for (var i = 0; i < n; i++) {
dp[i] = new Array(n);
dp[i].fill(-1)
}
var myBest = utill(nums, dp, 0, n-1);
return 2*myBest >= nums.reduce(function(a, b){return a+b;});
};
var utill = function(v, dp, i, j){
if(i > j) return 0;
if(dp[i][j] != -1) return dp[i][j];
var a = v[i] + Math.min(utill(v,dp, i+1, j-1), utill(v, dp, i+2, j));
var b = v[j] + Math.min(utill(v,dp,i, j-2), utill(v,dp, i+1, j-1));
dp[i][j] = Math.max(a, b);
return dp[i][j];
};
```

Golang, a little messy:

```
func PredictTheWinner(nums []int) bool {
if len(nums) % 2 == 0 { return true}
n := len(nums)
dp := make([][]int, n)
for i, _ := range dp {
dp[i] = make([]int, n)
for a, _:= range dp[i] {
dp[i][a] = -1
}
}
myBest := helper(nums, dp, 0, n-1)
sums := 0
for k,_ := range nums {
sums += nums[k]
}
return 2*myBest >= sums
}
func helper (v []int, dp [][]int, i int, j int) int {
if i > j { return 0 }
if dp[i][j] != -1 { return dp[i][j] }
a:= v[i] + helper(v,dp, i+1, j-1)
if a > v[i] + helper(v, dp, i+2, j) {
a = v[i] + helper(v, dp, i+2, j)
}
b:= v[j] + helper(v,dp,i, j-2)
if b > v[j] + helper(v,dp, i+1, j-1) {
b = v[j] + helper(v,dp, i+1, j-1)
}
dp[i][j] = a
if b > a {
dp[i][j] = b
}
return dp[i][j];
}
```