Taro and Jiro play a game with a given sequence of numbers. They take turns removing elements from the beginning or end of the sequence and earn points based on the removed element. Taro aims to maximize his total points minus Jiro's total points, while Jiro aims to minimize the difference. Given optimal play, find the resulting difference between Taro's and Jiro's total points. The input consists of the sequence length and the sequence itself. Output the resulting difference. All input values are integers, and the sequence length is between 1 and 3000, with each element in the sequence between 1 and 10^9. The output may not fit into a 32-bit integer type.

# Buggy version:
N=int(input())
a = list(map(int, input().split()))

dp=[[0 for i in range(N+1)] for j in range(N+1)]
for i in range(1,N+1):
    dp[i][i]=a[i-1]
for j in range(1,N+1):
    for i in reversed(range(1,N+1)):
        if i>j:
            continue
        if i==j:
            dp[i][j]=a[i-1]
        if i<j:
            dp[i][j]=max(a[i-1]-dp[i+1][j],a[j-1]-dp[i][j-1])
print(dp[1][N]

# Fixed version:
N=int(input())
a = list(map(int, input().split()))

dp=[[0 for i in range(N+1)] for j in range(N+1)]
for i in range(1,N+1):
    dp[i][i]=a[i-1]
for j in range(1,N+1):
    for i in reversed(range(1,N+1)):
        if i>j:
            continue
        if i==j:
            dp[i][j]=a[i-1]
        if i<j:
            dp[i][j]=max(a[i-1]-dp[i+1][j],a[j-1]-dp[i][j-1])
print(dp[1][N])

# Buggy version:
n = int(input())
arr = list(map(int, input().strip().split()))

mem = [[0 for i in range(n)] for i in range(n)]
for i in range(n):
    mem[i][i] = arr[i]

for diff in range(1, n):
    for L in range(n-diff):
        H = L+diff
        print(L, H, n, i)
        mem[L][H] = max(arr[L]-mem[L+1][H], arr[H]-mem[L][H-1])

print(mem[0][n-1])

# Fixed version:
n = int(input())
arr = list(map(int, input().strip().split()))

mem = [[0 for i in range(n)] for i in range(n)]
for i in range(n):
    mem[i][i] = arr[i]

for diff in range(1, n):
    for L in range(n-diff):
        H = L+diff
        mem[L][H] = max(arr[L]-mem[L+1][H], arr[H]-mem[L][H-1])

print(mem[0][n-1])

# Buggy version:
n = int(input())
arr = list(map(int, input().split()))

dp = [[0] * (n+1) for _ in range(n+1)]

for length in range(1, n + 1):
    for i in range(n - length + 1):
        j = i + length

        if ((n - length) % 2 == 0):
            dp[i][j] = max(dp[i+1][j] + arr[i], dp[i][j-1] + arr[j-1])
        else:
            dp[i][j] = min(dp[i+1][j] - arr[i], dp[i][j-1] - arr[j-1])

        print(i,j,dp[i][j])

print(dp[0][n])

# Fixed version:
n=int(input())
arr=list(map(int,input().split()))
dp=[[0]*n for _ in range(n)]
for i in range(n):
  if n%2==0:
    dp[i][i]=-arr[i]
  else:
    dp[i][i]=arr[i]
for i in range(1,n):
  for j in range(n-i):
    if (n-i)%2==0:
      dp[j][j+i]=min(dp[j][j+i-1]-arr[j+i],dp[j+1][j+i]-arr[j])
    else:
      dp[j][j+i]=max(dp[j][j+i-1]+arr[j+i],dp[j+1][j+i]+arr[j])
print(dp[0][n-1])

# Buggy version:
n = int(input())
a = list(map(int, input().split()))
dp = [[0] * (n-t+1) for t in range(1, n+1)]
dp[0] = a
for t in range(1, n):
    for i in range(n-t):
        dp[t][i] = max(-dp[t-1][i+1] + a[i], -dp[t-1][i] + a[i+t])
print(dp)
print(dp[n-1][0])

# Fixed version:
n = int(input())
a = list(map(int, input().split()))
dp = [[0] * (n-t+1) for t in range(1, n+1)]
dp[0] = a
for t in range(1, n):
    for i in range(n-t):
        dp[t][i] = max(-dp[t-1][i+1] + a[i], -dp[t-1][i] + a[i+t])
print(dp[n-1][0])

# Buggy version:
N = int(input())
a = list(map(int, input().split()))
dp = [[0 for j in range(10)] for i in range(10)]
for len in range(1,N+1):
    for i in range(N-len+1):
        j = len + i

        if (N - len) % 2 == 0:
            dp[i][j] = max(dp[i+1][j] + a[i], dp[i][j-1] + a[j-1])
        else:
            dp[i][j] = min(dp[i+1][j] - a[i], dp[i][j-1] - a[j-1])

print(dp[0][N])

# Fixed version:
N = int(input())
a = list(map(int, input().split()))
dp = [[0 for i in range(N+1)] for j in range(N+1)]
for len in range(1, N+1):
    for i in range(N - len + 1):
        j  = i + len
        if (N - len) % 2 == 0:
            dp[i][j] = max(dp[i+1][j] + a[i], dp[i][j-1] + a[j-1])
        else:
            dp[i][j] = min(dp[i+1][j] - a[i], dp[i][j-1] - a[j-1])
print(dp[0][N])

# Buggy version:
N = int(input())
A = list(map(int,input().split()))
A = [0]
dp = [[0] * (N+1) for _ in range(N+1)]

#半開区間で考える⇒[i,j)での最適解
for w in range(1,N+1):#区間の残り数
    for l in range(N):# 左端
        r = l + w#右端
        if r > N:
            continue
        elif (N-k) % 2 == 0:#太郎
            #print(i,x)
            dp[l][x] = max(dp[l+1][x] + A[l], dp[l][r-1] + A[r-1])
        elif (N-k) % 2 == 1:#次郎
            #print(i,x)
            dp[l][x] = min(dp[l+1][x] - A[l], dp[l][r-1] - A[r-1])
            
print(dp)

# Fixed version:
N = int(input())
A = list(map(int,input().split()))
dp = [[0] * (N+1) for _ in range(N+1)]

#半開区間で考える⇒[i,j)での最適解
for w in range(1,N+1):#区間の残り数
    for l in range(N):# 左端
        r = l + w#右端
        if r > N:
            continue
        elif (N-w) % 2 == 0:#太郎
            dp[l][r] = max(dp[l+1][r] + A[l], dp[l][r-1] + A[r-1])
        elif (N-w) % 2 == 1:#次郎
            dp[l][r] = min(dp[l+1][r] - A[l], dp[l][r-1] - A[r-1])
            
print(dp[0][N])

# Buggy version:
n=int(input())
a=list(map(int,input().split()))
dp=[[float("inf")]*(n+1) for _ in range(n+1)]
z=0
for l in range(n):
    dp[l][l]=0

for k in range(1,n+1):
    for i in range(n-k+1):
        j=i+k
   
        if (n-(i+j))%2==0: #先手
            dp[i][j]=max(dp[i+1][j]+a[i],dp[i][j-1]+a[j-1])
        else:
            dp[i][j]=min(dp[i+1][j]-a[i],dp[i][j-1]-a[j-1])
print(dp[0][n])

# Fixed version:
n=int(input())
a=list(map(int,input().split()))
dp=[[float("inf")]*(n+1) for _ in range(n)]
z=0
for l in range(n):
    dp[l][l]=0
for k in range(1,n+1):
    for i in range(n):
        j=i+k
        if 0<=i<=n-2 and 1<=j<=n:
            if (n-(i+j))%2==0: #先手
                dp[i][j]=max(dp[i+1][j]+a[i],dp[i][j-1]+a[j-1])
            else:
                dp[i][j]=min(dp[i+1][j]-a[i],dp[i][j-1]-a[j-1])
        elif 0<=i<=n-2 and 0<=j<=n:
            dp[i][j]=dp[i+1][j]+a[i]
        elif 0<=i<=n-1 and 1<=j<=n:
            dp[i][j]=dp[i][j-1]+a[j-1]
        else:
            z=1

print(dp[0][n])

# Buggy version:
def f(l,beg,end):
    if beg>=end:
        return 0
    if dp[beg][end]!=-1:
        return dp[beg][end]
    ans1=l[beg]+min(f(l,beg+2,end),f(l,beg+1,end-1))
    ans2=l[end]+min(f(l,beg,end-2),f(l,beg+1,end-1))
    dp[beg][end]=max(ans1,ans2)
    return max(ans1,ans2)

n = int(input())
l = list(map(int, input().split()))
tl = sum(l)
dp=[]
for _ in range(n):
    dp.append([-1]*n)
a = f(l,0,n-1)
b = tl-a
print(a-b)

# Fixed version:
import sys

def f(l,beg,end):
    if beg==end:
        dp[beg][end]=l[beg]
        return l[beg]
    if beg+1==end:
        dp[beg][end] = max(l[beg],l[end]) 
        return max(l[beg],l[end])
    if dp[beg][end]!=-1:
        return dp[beg][end]
    ans1=l[beg]+min(f(l,beg+2,end),f(l,beg+1,end-1))
    ans2=l[end]+min(f(l,beg,end-2),f(l,beg+1,end-1))
    dp[beg][end]=max(ans1,ans2)
    return max(ans1,ans2)

n = int(input())
l = list(map(int, input().split()))
tl = sum(l)
dp=[]
for _ in range(n):
    dp.append([-1]*n)
a = f(l,0,n-1)
b = tl-a
print(a-b)

# Buggy version:
n=int(sys.stdin.readline())
a=list(map(int,sys.stdin.readline().split()))
dp=[[0 for i in range(n)] for j in range(n)]
for i in range(n):
    dp[i][i]=a[i]
for i in range(2,n+1):
    for j in range(n-i+1):
        k=j+i-1 
        dp[j][k]=max(a[k]-dp[j][k-1],a[j]-dp[j+1][k])
print(dp[0][len(a)-1])

# Fixed version:
import sys
n=int(sys.stdin.readline())
a=list(map(int,sys.stdin.readline().split()))
dp=[[0 for i in range(n)] for j in range(n)]
for i in range(n):
    dp[i][i]=a[i]
for i in range(2,n+1):
    for j in range(n-i+1):
        k=j+i-1 
        dp[j][k]=max(a[k]-dp[j][k-1],a[j]-dp[j+1][k])
print(dp[0][len(a)-1])

# Buggy version:
n=int(input())
a=list(map(int,input().split()))
a=range(1,n+1)
dp=[[0]*n for _ in range(n)]
# dp[i][j]:i<=j,i番目からj番目までの数列(j-i+1個)を前にした時、ゲーム終了までに自分が取れる最大得点。i,j=0,..,n-1
sa=[0]
s=0
for ai in a:
      s+=ai
      sa.append(s)
for len in range(1,n+1):
      for l in range(n-len+1):
            r=l+len-1
            s=sa[r+1]-sa[l]
            dp[l][r]=max(s-dp[l][r-1],s-dp[l+1][r] if l+1<n else 0)
s=sum(a)
print(2*dp[0][-1]-sa[-1])


# Fixed version:
n=int(input())
a=list(map(int,input().split()))
dp=[[0]*n for _ in range(n)]
# dp[i][j]:i<=j,i番目からj番目までの数列(j-i+1個)を前にした時、ゲーム終了までに自分が取れる最大得点。i,j=0,..,n-1
sa=[0]
s=0
for ai in a:
      s+=ai
      sa.append(s)
for len in range(1,n+1):
      for l in range(n-len+1):
            r=l+len-1
            s=sa[r+1]-sa[l]
            dp[l][r]=max(s-dp[l][r-1],s-dp[l+1][r] if l+1<n else 0)
print(2*dp[0][-1]-sa[-1])

# Buggy version:
import sys
input = sys.stdin.readline

n = int(input())
a = [int(x) for x in input().split()]

dp = [[0]*(n + 1) for _ in range(n + 1)]

for i in range(n + 1):
    dp[i][i] = 0

for width in range(1, n + 1):
    for l in range(n + 1):
        r = width + l
        if r <= l or r > n:
            continue
        if (r - l) % 2 == 1:
            dp[l][r] = max(dp[l + 1][r] + a[l], dp[l][r - 1] + a[r - 1])
        else:
            dp[l][r] = min(dp[l + 1][r] - a[l], dp[l][r - 1] - a[r - 1])

print(dp[0][n])




# Fixed version:
import sys
input = sys.stdin.readline

n = int(input())
a = [int(x) for x in input().split()]

dp = [[0]*(n + 1) for _ in range(n + 1)]

for i in range(n + 1):
    dp[i][i] = 0

for width in range(1, n + 1):
    for l in range(n + 1):
        r = width + l
        if r <= l or r > n:
            continue
        if (n - (r - l)) % 2 == 0:
            dp[l][r] = max(dp[l + 1][r] + a[l], dp[l][r - 1] + a[r - 1])
        else:
            dp[l][r] = min(dp[l + 1][r] - a[l], dp[l][r - 1] - a[r - 1])

print(dp[0][n])

# Buggy version:
n = int(input())
*A, = map(int, input().split())
DP = [[0 for j in range(n+1)] for i in range(n+1)]
for l in range(1, n+1):
    for i in range(n-l+1):
        j = i+l
        DP[i][j] = max(A[i]-DP[i+1][j], A[j-1]-DP[i][j-1])
print(DP)

# Fixed version:
n = int(input())
*A, = map(int, input().split())
DP = [[0 for j in range(n+1)] for i in range(n+1)]
for l in range(1, n+1):
    for i in range(n-l+1):
        DP[i][i+l] = max(A[i]-DP[i+1][i+l], A[i+l-1]-DP[i][i+l-1])
print(DP[0][n])

# Buggy version:
n=int(input())
A=list(int(i) for i in input().split())
a=[0,0]
dp=[[a for i in range(n)] for j in range(n)]
for i in range(n-1,-1,-1):
    for j in range(i,n):
      if i==j:
        dp[i][j][0]=A[i]
        dp[i][j][1]=-A[i]
      else:
        dp[i][j][0]=max(A[i]+dp[i+1][j][1],A[j]+dp[i][j-1][1])
        dp[i][j][1]=-dp[i][j][0]
#print(dp[0][-1][0])
print(dp)


# Fixed version:
#dp=[[ for i in range(3000)] for j in range(3000)]
n=int(input())
A=list(int(i) for i in input().split())
dp=[[0 for i in range(n)] for j in range(n)]
for i in range(n-1,-1,-1):
    for j in range(i,n):
        if i==j:
            dp[i][j]=A[i]
        else:
            dp[i][j]=max(A[i]-dp[i+1][j],A[j]-dp[i][j-1])
print(dp[0][-1])

# Buggy version:
import sys

read = sys.stdin.read
sys.setrecursionlimit(10 ** 7)


def solve():
    n, *a = map(int, read().split())
    a = tuple(a)
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]
    for i in range(n - 2, -1, -1):
        for j in range(i + 1, n):
            L = a[i] - dp[i + 1][j]
            R = a[j] - dp[i][j - 1]
            if L > R:
                dp[i][j] = L
            else:
                dp[i][j] = R
    for i in dp:
        print(i)
    return dp[0][n - 1]


print(solve())


# Fixed version:
import sys

read = sys.stdin.read
sys.setrecursionlimit(10 ** 7)


def solve():
    n, *a = map(int, read().split())
    a = tuple(a)
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]
    for i in range(n - 2, -1, -1):
        for j in range(i + 1, n):
            L = a[i] - dp[i + 1][j]
            R = a[j] - dp[i][j - 1]
            if L > R:
                dp[i][j] = L
            else:
                dp[i][j] = R
    return dp[0][n - 1]


print(solve())

# Buggy version:
n=int(input())
a=[int(i) for i in input().split()]
#dp=[[0]*(n+1) for i in range(n+1)]
dp=[[0]*(n+1) for i in range(n)]

for w in range(1,n+1):
#for w in range(1,3,1):
#    print(dp[1])
    for l in range(n-w+1):
        print("#",l)
        r=l+w
        dpl=-dp[l+1][r]+a[l]
        dpr=-dp[l][r-1]+a[r-1]
        dp[l][r]=max(dpl,dpr)
#print()
#for i in dp:
#    print(i)
print(dp[0][n])


# Fixed version:
n=int(input())
a=[int(i) for i in input().split()]
dp=[[0]*(n+1) for i in range(n+1)]

for w in range(1,n+1):
#for w in range(1,3,1):
#    print(dp[1])
    for l in range(n-w+1):
        r=l+w
        dpl=-dp[l+1][r]+a[l]
        dpr=-dp[l][r-1]+a[r-1]
        dp[l][r]=max(dpl,dpr)
#print()
#for i in dp:
#    print(i)
print(dp[0][n])

# Buggy version:
import numpy as np

n = int(input())
a = np.array([int(i) for i in input().split()], dtype=np.int64)

s = np.copy(a)
for i in range(1, n):
    s = np.maximum(a[:n-i]-s[1:n-i+1], a[i:]-s[:n-i])
    print(i, s)

print(s[0])


# Fixed version:
import numpy as np

n = int(input())
a = np.array([int(i) for i in input().split()], dtype=np.int64)

s = np.copy(a)
for i in range(1, n):
    s = np.maximum(a[:n-i]-s[1:n-i+1], a[i:]-s[:n-i])

print(s[0])

# Buggy version:
n = int(input())
a = tuple(map(int, input().split()))
dp = [(0,) * n for _ in range(n)]
for i in range(n):
    dp[i][i] = a[i]

for i in range(n - 2, -1, -1):
    for j in range(i + 1, n):
        dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])

print(dp[0][n - 1])

# Fixed version:
n = int(input())
a = tuple(map(int, input().split()))
dp = [[0] * n for _ in range(n)]
for i in range(n):
    dp[i][i] = a[i]

for i in range(n - 2, -1, -1):
    for j in range(i + 1, n):
        dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])

print(dp[0][n - 1])

# Buggy version:
n = int(input())
a = list(map(int, input().split()))

def calc():
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]

    for i in range(n - 2, -1, -1):
        for j in range(i + 1, n):
            dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])

dp = calc()
print(dp[0][n - 1])

# Fixed version:
n = int(input())
a = list(map(int, input().split()))

def calc():
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]

    for i in range(n - 2, -1, -1):
        for j in range(i + 1, n):
            dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])
    return dp

dp = calc()
print(dp[0][n - 1])

# Buggy version:
n = int(input())
a = list(map(int, input().split()))

dp=[]
for i in range(n):
	dp.append(0)
for i in range(n):
    dp[i][i] = a[i]

for i in range(n - 2, -1, -1):
    for j in range(i + 1, n):
        dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])

print(dp[0][n - 1])

# Fixed version:
n = int(input())
a = list(map(int, input().split()))

dp=[]
for i in range(n):
	dp.append([0]*n)
for i in range(n):
    dp[i][i] = a[i]

for i in range(n - 2, -1, -1):
    for j in range(i + 1, n):
        dp[i][j] = max(a[i] - dp[i + 1][j], a[j] - dp[i][j - 1])

print(dp[0][n - 1])

# Buggy version:
def kukan(n, a):
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]
    for i in range(n - 2, -1, -1):
        g0 = dp[i]
        g1 = dp[i + 1]
        for j in range(i + 1, n):
            L = a[i] - g1[j]
            R = a[j] - g0[j - 1]
            dp[i][j] = L if L > R else R
    print(*dp,sep="\n")
    return dp[0][n - 1]


n = int(input())
a = list(map(int, input().split()))
print(kukan(n, a))

# Fixed version:
def kukan(n, a):
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = a[i]
    for i in range(n - 2, -1, -1):
        g0 = dp[i]
        g1 = dp[i + 1]
        for j in range(i + 1, n):
            L = a[i] - g1[j]
            R = a[j] - g0[j - 1]
            dp[i][j] = L if L > R else R
    return dp[0][n - 1]


n = int(input())
a = list(map(int, input().split()))
print(kukan(n, a))

# Buggy version:
import sys
# input処理を高速化する
input = sys.stdin.readline
def chmax(a, b):
    if a >= b:
        return a
    return b
def chmin(a, b):
    if a <= b:
        return a
    return b
def main():
    N = int(input())
    a = list(map(int, input().split()))
    # aiからajのX−Yの最大値
    # [左端,右端)=[l,r)からの遷移    
    # 左をとる[l+1,r)、右をとる[l,r−1)の2通り
    dp = [[0] * (N+1)  for _ in range(N+1)]
    print(dp)
    for len in range(1, N + 1):
        for i in range(N + 1 - len):
            j = i + len
            if (N - len) % 2 == 0:
                dp[i][j] = chmax(dp[i + 1][j] + a[i], dp[i][j - 1] + a[j - 1])
            else:
                dp[i][j] = chmin(dp[i + 1][j] - a[i], dp[i][j - 1] - a[j - 1])
    print(dp)
    print(dp[0][N])
main()

# Fixed version:
import sys
# input処理を高速化する
input = sys.stdin.readline

def chmax(a, b):
    if a >= b:
        return a
    return b

def chmin(a, b):
    if a <= b:
        return a
    return b

def main():
    N = int(input())
    a = list(map(int, input().split()))

    # aiからajのX−Yの最大値
    # [左端,右端)=[l,r)からの遷移    
    # 左をとる[l+1,r)、右をとる[l,r−1)の2通り
    dp = [[0] * (N+2)  for _ in range(N+2)]

    for len in range(1, N + 1):
        for i in range(N + 1 - len):
            j = i + len

            if (N - len) % 2 == 0:
                dp[i][j] = chmax(dp[i + 1][j] + a[i], dp[i][j - 1] + a[j - 1])
            else:
                dp[i][j] = chmin(dp[i + 1][j] - a[i], dp[i][j - 1] - a[j - 1])

    print(dp[0][N])

main()

# Buggy version:
from sys import stdin
input = stdin.readline

N = int(input())
a = list(map(int, input().split()))

dp = [[0] * (N + 1) for _ in range(N + 1)]

for i in range(N):
    dp[i][i + 1] = a[i] if N & 1 == 1 else -a[i]

for i in range(0, N - 1):
    for j in range(2, N + 1 - i):  # j is the length of the interval
        if (N - j) & 1 == 0:
            dp[i][i + j] = max(a[i + 1] + dp[i + 1][i + j],
                               a[i + j - 1] + dp[i][i + j - 1])
        else:
            dp[i][i + j] = min(dp[i + 1][i + j] - a[i + 1],
                               dp[i][i + j - 1] - a[i + j - 1])

print(dp[0][N])

# Fixed version:
from sys import stdin
input = stdin.readline

N = int(input())
a = list(map(int, input().split()))

dp = [[0] * (N + 1) for _ in range(N + 1)]

for i in range(N):
    dp[i][i + 1] = a[i] if N & 1 == 1 else -a[i]

for j in range(2, N + 1):
    for i in range(0, N + 1 - j):
        # j is the length of the interval + 1
        if (N - j) & 1 == 0:
            dp[i][i + j] = max(a[i] + dp[i + 1][i + j],
                               a[i + j - 1] + dp[i][i + j - 1])
        else:
            dp[i][i + j] = min(dp[i + 1][i + j] - a[i],
                               dp[i][i + j - 1] - a[i + j - 1])

print(dp[0][N])