You have N slimes lined up, each with a specific size. You want to combine them into one larger slime with the least total cost. To do this, you repeatedly choose two adjacent slimes and combine them into a new slime. The cost of combining two slimes is the sum of their sizes. Find the minimum possible total cost. The input consists of N and the sizes of the slimes, and the output is the minimum total cost.

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

s=[0]+list(itertools.accumulate(a))

dp=[[10**10]*(n+1) for _ in range(n)]
for l in range(n):
    dp[l][l+1]=0
for d in range(2,n+1): 
    for k in range(1,d):
        for i in range(n-d+1):
            j=i+d
            S=s[j]-s[i]
            dp[i][j]=min(dp[i][i+k]+dp[i+k][j],dp[i][j])+S

print(dp[0][n])

# Fixed version:
import itertools

n=int(input())
a=list(map(int,input().split()))
s=[0]+list(itertools.accumulate(a))

dp=[[10**20]*(n+1) for _ in range(n)]
for l in range(n):
    dp[l][l+1]=0
for d in range(2,n+1): 
    for k in range(1,d):
        for i in range(n-d+1):
            j=i+d
            S=s[j]-s[i]
            dp[i][j]=min(dp[i][i+k]+dp[i+k][j]+S,dp[i][j])

print(dp[0][n])

# Buggy version:
import sys
sys.setrecursionlimit(10**8)
INF = float("inf")

def findsum(li):

    for i in range(1,len(li)+1):
        tot[i]=tot[i-1]+li[i-1]
    #print(tot)

def findans(start,end,li):
  global tot
  #print("HI")
  if(start>=end):
    return 0
  if(dp[start][end]!=-1):
    return dp[start][end]
  ans = INF
  for k in range(start,end+1):


      ans=min(findans(start,k,li)+findans(k+1,end,li),ans)
  dp[start][end]=ans+(tot[end+1]-tot[start])
  return dp[start][end]
n=int(input())
li=[int(k) for k in input().split()]
tot=[0]*(len(li)+1)
findsum(li)
dp=[[-1 for i in range(n)]for k in range(n)]
print(findans(0,n-1,li))


# Fixed version:
import sys
sys.setrecursionlimit(10**8)
INF = float("inf")

def findsum(li):

    for i in range(1,len(li)+1):
        tot[i]=tot[i-1]+li[i-1]
    #print(tot)

def findans(start,end,li):
  global tot
  #print("HI")
  if(start>=end):
    return 0
  if(dp[start][end]!=-1):
    return dp[start][end]
  ans = INF
  for k in range(start,end):


      ans=min(findans(start,k,li)+findans(k+1,end,li),ans)
  dp[start][end]=ans+(tot[end+1]-tot[start])
  return dp[start][end]
n=int(input())
li=[int(k) for k in input().split()]
tot=[0]*(len(li)+1)
findsum(li)
dp=[[-1 for i in range(n)]for k in range(n)]
print(findans(0,n-1,li))

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

dp = []
dp2 = []
aac = []

def fdp(l, r):
    global dp, dp2
    if dp2[l][r]:
        return dp[l][r]
    else:
        dp2[l][r] = 1
        if l == r:
            return 0
        result_tmp = float('inf')
        for kugiri in range(l, r):
            result_tmp = min(result_tmp, fdp(l, kugiri) + fdp(kugiri+1, r))
        result = result_tmp + (aac[r+1] - aac[l])
        dp[l][r] = result
        return result


def main():
    global dp, dp2, aac
    n = int(input())
    a = tuple(map(int, input().split()))
    aac = list(accumulate(a))
    aac = tuple(chain([0], aac))
    dp = [[0] * n for _ in range(n)]
    dp2 = [[0] * n for _ in range(n)]

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


if __name__ == '__main__':
    main()

# Fixed version:
from itertools import accumulate
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
from itertools import chain

dp = []
dp2 = []
aac = []

def fdp(l, r):
    global dp, dp2
    if dp2[l][r]:
        return dp[l][r]
    else:
        dp2[l][r] = 1
        if l == r:
            return 0
        result_tmp = float('inf')
        for kugiri in range(l, r):
            result_tmp = min(result_tmp, fdp(l, kugiri) + fdp(kugiri+1, r))
        result = result_tmp + (aac[r+1] - aac[l])
        dp[l][r] = result
        return result
def main():
    global dp, dp2, aac
    n = int(input())
    a = tuple(map(int, input().split()))
    aac = list(accumulate(a))
    aac = tuple(chain([0], aac))
    dp = [[0] * n for _ in range(n)]
    dp2 = [[0] * n for _ in range(n)]
    fdp(0, n - 1)
    print(dp[0][-1])
if __name__ == '__main__':
    main()

# Buggy version:
from itertools import accumulate

n = int(input())
A = list(map(int, input().split()))
infi = 10 ** 20
SA = list(accumulate([0] + A))

dp = [[infi] * (n + 1) for _ in range(n + 1)]
# dp[i]左からi個決めた時の最小値とする。
if n >= 3:
    for i in range(n):
        dp[i][i] = 0
        dp[i][i + 1] = 0
        if i <= n - 2:
            dp[i][i + 2] = A[i] + A[i + 1]
    for d in range(n + 1):
        for i in range(n):
            j = i + d
            if j > n:
                continue
            if d >= 2:
                for m in range(i + 1, j + 1):
                    dp[i][j] = min(dp[i][j], dp[i][m] + dp[m][j] + SA[j] - SA[i])
    print(dp[0][n])
else:


# Fixed version:
from itertools import accumulate

n = int(input())
A = list(map(int, input().split()))
infi = 10 ** 20
SA = list(accumulate([0] + A))

dp = [[infi] * (n + 1) for _ in range(n + 1)]
# dp[i]左からi個決めた時の最小値とする。
if n >= 3:
    for i in range(n):
        dp[i][i] = 0
        dp[i][i + 1] = 0
        if i <= n - 2:
            dp[i][i + 2] = A[i] + A[i + 1]
    for d in range(n + 1):
        for i in range(n):
            j = i + d
            if j > n:
                continue
            if d >= 2:
                for m in range(i + 1, j + 1):
                    dp[i][j] = min(dp[i][j], dp[i][m] + dp[m][j] + SA[j] - SA[i])
    print(dp[0][n])
else:
    print(sum(A))

# Buggy version:
from itertools import accumulate

N, *A = map(int, open(0).read().split())

S = [0] + list(accumulate(A))

memo = [[-1] * N for _ in range(N)]
def dp(L, R):
    if L == R:
        return 0
    if memo[L][R] >= 0:
        return memo[L][R]

    memo[L][R] = min(dp(L, c) + dp(c + 1, R) + S[R + 1] - S[L] for c in range(L, R))
    return memo[L][R]

# Fixed version:
from itertools import accumulate

N, *A = map(int, open(0).read().split())

S = [0] + list(accumulate(A))

memo = [[-1] * N for _ in range(N)]
def dp(L, R):
    if L == R:
        return 0
    if memo[L][R] >= 0:
        return memo[L][R]

    memo[L][R] = min(dp(L, c) + dp(c + 1, R) + S[R + 1] - S[L] for c in range(L, R))
    return memo[L][R]

print(dp(0, N - 1))

# Buggy version:
N=int(input())
A=list(map(int,input().split()))
a=[0]*(N+1)
for i in range(N):
    a[i+1]=a[i]+A[i]
print(a)
d=[[0]*(N+1) for i in range(N+1)]
for w in range(2,N+1):
    for l in range(N+1-w):
        d[l][l+w]=min([d[l][m]+d[m][l+w] for m in range(l+1,l+w)])+a[l+w]-a[l]
print(d[0][N])

# Fixed version:
N=int(input())
A=list(map(int,input().split()))
a=[0]*(N+1)
for i in range(N):
    a[i+1]=a[i]+A[i]
d=[[0]*(N+1) for i in range(N+1)]
for w in range(2,N+1):
    for l in range(N+1-w):
        d[l][l+w]=min([d[l][m]+d[m][l+w] for m in range(l+1,l+w)])+a[l+w]-a[l]
print(d[0][N])

# Buggy version:
n = int(input())
ns = list(map(int, input().split()))
dp = [[0] * n for i in range(n)]
for i in range(n-1): 
    dp[i][i+1] = ns[i] + ns[i+1]
cur = [0]
cnt = 0
for i in ns:
    cnt += i
    cur.append(cnt)

for i in range(n-1, -1, -1):
    for j in range(i + 2, n):
        dp[i][j] = min(dp[i][k] + dp[k + 1][j] for k in range(i + 1, j)) + cur[j] - cur[i]
print(dp[0][-1])

# Fixed version:
n = int(input())
ns = list(map(int, input().split()))
dp = [[0] * n for i in range(n)]
cur = [0]
cnt = 0
for i in ns:
    cnt += i
    cur.append(cnt)

for i in range(n-1, -1, -1):
    for j in range(i + 1, n):
        dp[i][j] = min(dp[i][k] + dp[k + 1][j] for k in range(i, j)) + cur[j+1] - cur[i]
print(dp[0][-1])

# Buggy version:
from itertools import accumulate


def dfs(l, r):
    if memo[l][r]:
        return dp[l][r]
    for i in range(l, r):
        dp[l][r] = min(max(0, dp[l][r]), dfs(l, i) + dfs(i + 1, r) + acc_A[r] - acc_A[l - 1])
    memo[l][r] = True
    return dp[l][r]


n = int(input())
A = list(map(int, input().split()))
acc_A = [0] + list(accumulate(A))

INF = 10 ** 18
dp = [[INF] * (n + 1) for _ in range(n + 1)]
memo = [[False] * (n + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    dp[i][i] = 0
    memo[i][i] = True


print(dfs(1, n))
[print(row) for row in memo]


# Fixed version:
from itertools import accumulate


def dfs(l, r):
    if memo[l][r]:
        return dp[l][r]
    for i in range(l, r):
        dp[l][r] = min(max(0, dp[l][r]), dfs(l, i) + dfs(i + 1, r) + acc_A[r] - acc_A[l - 1])
    memo[l][r] = True
    return dp[l][r]


n = int(input())
A = list(map(int, input().split()))
acc_A = [0] + list(accumulate(A))

INF = 10 ** 18
dp = [[INF] * (n + 1) for _ in range(n + 1)]
memo = [[False] * (n + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    dp[i][i] = 0
    memo[i][i] = True


print(dfs(1, n))

# Buggy version:
N=int(input())
A=list(map(int,input().split()))
import numpy
B=[0]+list(numpy.cumsum(A))
print(B)
dp=[[0]*(N+1) for i in range(N)]
#k:いくつのスライムを合体しているか
for k in range(2,N+1):
  #i:どこのスライムを起点に合体しているか
  for i in range(N-k+1):
    dp[i][k]=min(dp[i][j]+dp[i+j][k-j] for j in range(1,k))+B[i+k]-B[i]
print(dp[0][N])

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

dp=[[0]*(N+1) for i in range(N)]
#k:いくつのスライムを合体しているか
for k in range(2,N+1):
  #i:どこのスライムを起点に合体しているか
  for i in range(N-k+1):
    dp[i][k]=min(dp[i][j]+dp[i+j][k-j] for j in range(1,k))+B[i+k]-B[i]
print(dp[0][N])

# Buggy version:
from functools import lru_cache
N = int(input())
A = list(map(int, input().split()))

INF = 1.0e+100


dp = [[[None, INF] for _ in range(N+1)] for _ in range(N+1)]
for i in range(N):
    dp[i][i+1] = [A[i], 0]

for g in range(2, N+1):
    for l in range(N-g+1):
        r = l + g
        print(l, r)
        for i in range(l+1, r):
            lv, lc = dp[l][i]
            rv, rc = dp[i][r]
            nc = lv + rv + lc + rc
            print(l, i, r, lv, rc, lc, rc)
            if dp[l][r][1] > nc:
                dp[l][r][0] = lv + rv
                dp[l][r][1] = nc

print(dp[0][N][1])


# Fixed version:
from functools import lru_cache
N = int(input())
A = list(map(int, input().split()))

INF = 1.0e+100


dp = [[[None, INF] for _ in range(N+1)] for _ in range(N+1)]
for i in range(N):
    dp[i][i+1] = [A[i], 0]

for g in range(2, N+1):
    for l in range(N-g+1):
        r = l + g
        for i in range(l+1, r):
            lv, lc = dp[l][i]
            rv, rc = dp[i][r]
            nc = lv + rv + lc + rc
            if dp[l][r][1] > nc:
                dp[l][r][0] = lv + rv
                dp[l][r][1] = nc

print(dp[0][N][1])

# Buggy version:

def asum(l,r):
	global cumsum
	l+=1
	r+=1
	return cumsum[r-1]-cumsum[l-1]
def check(l,r):
	global dp
	if l==r:
		return 0
	if l == r-1:
		return arr[l]+arr[r]
	if dp[l][r] != None:
		return dp[l][r]
	else:
		ans = 10**9
		for i in range(l, r):
			st1 = asum(l,i)
			st2 = asum(i,r+1)
			ans = min(st1 + st2 + check(l,i)+ check(i+1, r), ans)
		
		dp[l][r] = ans
		return ans





ll = int(input())
arr = [int(i) for i in input().split()]
cumsum = [0]

for i in arr:
	cumsum.append(cumsum[-1]+i)
dp = [[None for i in range(ll+1)] for j in range(ll+1)]
print(check(0, ll-1))


# Fixed version:

def asum(l,r):
	global cumsum
	l+=1
	r+=1
	return cumsum[r-1]-cumsum[l-1]
def check(l,r):
	global dp
	if l==r:
		return 0
	if l == r-1:
		return arr[l]+arr[r]
	if dp[l][r] != None:
		return dp[l][r]
	else:
		ans = 10**18
		for i in range(l, r):
			st1 = asum(l,i)
			st2 = asum(i,r+1)
			ans = min(st1 + st2 + check(l,i)+ check(i+1, r), ans)
		
		dp[l][r] = ans
		return ans





ll = int(input())
arr = [int(i) for i in input().split()]
cumsum = [0]

for i in arr:
	cumsum.append(cumsum[-1]+i)
dp = [[None for i in range(ll+1)] for j in range(ll+1)]
print(check(0, ll-1))

# Buggy version:
import sys
sys.setrecursionlimit(10**8)

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

s = [0]*N
s[0] = a[0]
for i in range(1, N):
    s[i] += s[i-1]+a[i]
s = [0]+s

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


def solve(l, r):
    if l == r:
        return 0
    if dp[l][r] > 0:
        return dp[l][r]

    n = 10**9
    m = s[r+1]-s[l]
    for i in range(l, r):
        n = min([n, solve(l, i)+solve(i+1, r)+m])
    dp[l][r] = n
    return n


print(solve(0, N-1))


# Fixed version:
import sys
sys.setrecursionlimit(10**8)

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

s = [0]*N
s[0] = a[0]
for i in range(1, N):
    s[i] += s[i-1]+a[i]
s = [0]+s

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


def solve(l, r):
    if l == r:
        return 0
    if dp[l][r] > 0:
        return dp[l][r]

    n = float('inf')
    m = s[r+1]-s[l]
    for i in range(l, r):
        n = min([n, solve(l, i)+solve(i+1, r)+m])
    dp[l][r] = n
    return n


print(solve(0, N-1))

# Buggy version:
N = int(input())
As = list(map(int, input().split()))
ma = sum(As)
o = dict()
INF = 10**19
from itertools import accumulate
aa = [0] + list(accumulate(As))

for i in range(N):
    for j in range(N-i):
        span = i*N+j
        # 長さi+1, 開始位置jの合成コスト+構成要素の和
        if i == 0:
            o[span] = As[j]
            continue
        C = INF
#        print(i,j,o)
        for k in range(i):
            # 長さk+1とi+1-(k+1)=i-kに分割
#            print(i,j,k*N+j, (i-k-1)*N+j+k)
            C = min(C, o[k*N+j]+o[(i-k-1)*N+j+k])
#        o[span] = C + sum(As[j:j+i+1])
        o[span] = C + aa[j+i+1] - aa[j]

print(o[span]-ma)


# Fixed version:
N = int(input())
As = list(map(int, input().split()))
ma = sum(As)
o = dict()
INF = 10**19
from itertools import accumulate
aa = [0] + list(accumulate(As))

for i in range(N):
    for j in range(N-i):
        span = i*N+j
        # 長さi+1, 開始位置jの合成コスト+構成要素の和
        if i == 0:
            o[span] = As[j]
            continue
        C = INF
#        print(i,j,o)
        for k in range(i):
            # 長さk+1とi+1-(k+1)=i-kに分割
#            print(i,j,k*N+j, (i-k-1)*N+j+k, o)
            C = min(C, o[k*N+j]+o[(i-k-1)*N+j+k+1])
#        o[span] = C + sum(As[j:j+i+1])
        o[span] = C + aa[j+i+1] - aa[j]

print(o[span]-ma)

# Buggy version:
import sys
sys.setrecursionlimit(160000)

N = int(input())
A = [int(a) for a in input().split()]

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

for i in range(N):
    flag[i][i] = True

S[0] = A[0]
for i in range(N):
    S[i+1] = S[i]+A[i]
    
def f(l, r):
    if flag[l][r]:
        return dp[l][r]
    flag[l][r] = True
    res = 10**12
    for m in range(l, r):
        res = min(res, f(l, m)+f(m+1, r))
    dp[l][r] = res+S[r+1]-S[l]
    return dp[l][r]

print(f(0, N-1), dp)

# Fixed version:
import sys
sys.setrecursionlimit(160000)

N = int(input())
A = [int(a) for a in input().split()]

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

for i in range(N):
    flag[i][i] = True

S[0] = A[0]
for i in range(N):
    S[i+1] = S[i]+A[i]
    
def f(l, r):
    if flag[l][r]:
        return dp[l][r]
    flag[l][r] = True
    res = 10**18
    for m in range(l, r):
        res = min(res, f(l, m)+f(m+1, r))
    dp[l][r] = res+S[r+1]-S[l]
    return dp[l][r]

print(f(0, N-1))

# Buggy version:
def p_n():
    from itertools import accumulate
    n = int(input())
    *a, = map(int, input().split())
    ac = list(accumulate(a)) + [0]
    dp = [[0] * (n + 1) for _ in range(n + 1)]
    for i in range(2, n + 1):
        for j in range(n - i + 1):
            dp[i][j] = ac[j + i - 1] - ac[j - 1] + min(dp[k][j] + dp[i - k][j + k] for k in range(1, i))
    print(dp)
    print(dp[-1][0])


if __name__ == '__main__':
    p_n()


# Fixed version:
def p_n():
    from itertools import accumulate
    n = int(input())
    *a, = map(int, input().split())
    ac = list(accumulate(a)) + [0]
    dp = [[0] * (n + 1) for _ in range(n + 1)]
    for i in range(2, n + 1):
        for j in range(n - i + 1):
            dp[i][j] = ac[j + i - 1] - ac[j - 1] + min(dp[k][j] + dp[i - k][j + k] for k in range(1, i))
    print(dp[-1][0])


if __name__ == '__main__':
    p_n()

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


n=int(input())
a=list(map(int, input().split()))
b=itertools.accumulate(a)
b=[0]+list(b)
dp=[[0]*(n) for i in range(n)]

x=float('inf')
for i in range(n-1,-1,-1):
    for j in range(i+1,n):
        for k in range(i,j):
            dp[i][j]=min(dp[i+1][k]+dp[k+1][j],x)+(b[j+1]-b[i])
print(b)
print(dp)

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


n=int(input())
a=list(map(int, input().split()))
b=itertools.accumulate(a)
b=[0]+list(b)
dp=[[0]*(n) for i in range(n)]

x=float('inf')
for i in range(n-1,-1,-1):
    for j in range(i+1,n):
        if j>=i+2:
            for k in range(i,j):
                x=min(dp[i][k]+dp[k+1][j],x)
            dp[i][j]=x+(b[j+1]-b[i])
            x=float('inf')
        else:
            dp[i][j]=b[j+1]-b[i]
print(dp[0][-1])

# Buggy version:
import sys

n = int(input())
INF = 10**9
a_ls = [int(i) for i in sys.stdin.readline().split()]
memo_ls = [[0 for j in range(n)] for i in range(n)]
for _ in range(1,n):
    for i in range(n-_):
        j = i + _
        sum_ij = sum(a_ls[i:j+1])
        memo_ls[i][j] = sum_ij
        res = INF if j - i > 1 else 0
        for k in range(i,j):
            res = min(memo_ls[i][k] + memo_ls[k+1][j], res)
        memo_ls[i][j] += res
print(memo_ls[0][-1])

# Fixed version:
import sys

n = int(input())
INF = 10**20
a_ls = [int(i) for i in sys.stdin.readline().split()]
memo_ls = [[0 for j in range(n)] for i in range(n)]
for _ in range(1,n):
    for i in range(n-_):
        j = i + _
        sum_ij = sum(a_ls[i:j+1])
        memo_ls[i][j] = sum_ij
        res = INF if j - i > 1 else 0
        for k in range(i,j):
            res = min(memo_ls[i][k] + memo_ls[k+1][j], res)
        memo_ls[i][j] += res
for i in range(n):
    memo_ls[i][i] = a_ls[i]
print(memo_ls[0][-1])

# Buggy version:
inf = float('inf')

def accmulate(array):
    global cs
    cs = [0]*(len(array)+1)
    for i in range(len(array)):
        cs[i+1] = cs[i] + array[i]

def query(l,r):
    return cs[r+1] - cs[l]

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

accmulate(A)

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

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

for b in range(3,N+1):
    for i in range(N-b+1):
        j = i + b
        for k in range(i+1,j):
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + query(i,j-1))

ans = dp[0][N]
print(ans)

# Fixed version:
inf = float('inf')

def accmulate(array):
    global cs
    cs = [0]*(len(array)+1)
    for i in range(len(array)):
        cs[i+1] = cs[i] + array[i]

def query(l,r):
    return cs[r+1] - cs[l]

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

accmulate(A)

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

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

for i in range(N-1):
    dp[i][i+2] = A[i] + A[i+1]

for b in range(3,N+1):
    for i in range(N-b+1):
        j = i + b
        for k in range(i+1,j):
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + query(i,j-1))

ans = dp[0][N]
print(ans)

# Buggy version:
import fileinput


def solve_slimes(slimes):
    slime_union_table = [0] * len(slimes) * len(slimes)
    slime_cost_table = [0] * len(slimes) * len(slimes)

    for i in range(len(slimes)):
        slime_union_table[i] = slimes[i]

    for gap in range(1, len(slimes)):
        for li in range(len(slimes) - gap):
            split_size = slime_union_table[li] + slime_union_table[li + 1 + (gap - 1) * len(slimes)]
            slime_union_table[li + gap * len(slimes)] = split_size

            for split in range(0, gap):
                split_cost = slime_cost_table[li + split * len(slimes)] + slime_cost_table[li + split + 1 + (gap - split - 1) * len(slimes)] + split_size

                if slime_cost_table[li + gap * len(slimes)] == 0:
                    slime_cost_table[li + gap * len(slimes)] = split_cost

                else:
                    slime_cost_table[li + gap * len(slimes)] = min(
                        split_cost,
                        slime_cost_table[li + gap * len(slimes)]
                    )
    return slime_cost_table[len(slimes) * (len(slimes) - 1)]


inp = fileinput.FileInput()

inp.readline()
slimes = [int(v) for v in inp.readline().split()]

print(solve_slimes(slimes)

# Fixed version:
import fileinput


def solve_slimes(slimes):
    slime_union_table = [0] * len(slimes) * len(slimes)
    slime_cost_table = [0] * len(slimes) * len(slimes)

    for i in range(len(slimes)):
        slime_union_table[i] = slimes[i]

    for gap in range(1, len(slimes)):
        for li in range(len(slimes) - gap):
            split_size = slime_union_table[li] + slime_union_table[li + 1 + (gap - 1) * len(slimes)]
            slime_union_table[li + gap * len(slimes)] = split_size

            for split in range(0, gap):
                split_cost = slime_cost_table[li + split * len(slimes)] + slime_cost_table[li + split + 1 + (gap - split - 1) * len(slimes)] + split_size

                if slime_cost_table[li + gap * len(slimes)] == 0:
                    slime_cost_table[li + gap * len(slimes)] = split_cost

                else:
                    slime_cost_table[li + gap * len(slimes)] = min(
                        split_cost,
                        slime_cost_table[li + gap * len(slimes)]
                    )
    return slime_cost_table[len(slimes) * (len(slimes) - 1)]


inp = fileinput.FileInput()

inp.readline()
slimes = [int(v) for v in inp.readline().split()]

print(solve_slimes(slimes))

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

#dp[l][r] = [l, r)区間のスライムを
dp = [[float("inf")]*(n+1) for i in range(n+1)]
for i in range(n):
    dp[i][i] = 0

#cost[r]-cost[l] = [l, r)区間を合計したときのスライムの総和
cost = [0]*(n+1)
for i in range(n):
    cost[i+1] = cost[i] + a[i]

#メモ化再帰でdp[0][n]求める
def dfs(l, r):
    if dp[l][r] != float("inf"):
        return dp[l][r]
    else:
        res = float("inf")
        if (r - l) == 1:
            dp[l][r] = 0
            return dp[l][r]
        for k in range(l, r):
            if k == l or k == r:
                continue
            #dp[l][k] + dp[k][r] + 合体に必要なコスト
            res = min(res, dfs(l, k) + dfs(k, r) + (cost[r] - cost[l]))
            print(l,k,r,dfs(l, k) + dfs(k, r))
        dp[l][r] = res
    return dp[l][r]

print(dp[0][n])

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

#dp[l][r] = [l, r)区間のスライムを合体するときのコストの最小値
dp = [[-1]*(n+1) for i in range(n+1)]
for i in range(n):
    dp[i][i] = 0

#cost[r]-cost[l] = [l, r)区間を合計したときのスライムの総和
cost = [0]*(n+1)
for i in range(n):
    cost[i+1] = cost[i] + a[i]

#メモ化再帰でdp[0][n]求める
def dfs(l, r):
    if dp[l][r] != -1:
        return dp[l][r]
    elif (r - l) == 1:
        dp[l][r] = 0
        return dp[l][r]
    else:
        res = float("inf")
        for k in range(l + 1, r):
            #dp[l][k] + dp[k][r] + 合体に必要なコスト
            res = min(res, dfs(l, k) + dfs(k, r) + (cost[r] - cost[l]))
        dp[l][r] = res
    return dp[l][r]

dfs(0, n)
print(dp[0][n])

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

INF = float('inf')
dp = [[INF] * (n+1) for _ in range(n+1)]

acum = [0] * (n+1)
for i, ai in enumerate(a):
    acum[i+1] += acum[i] + ai

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

for l in range(2, n+1):
    for i in range(n-l+1):
        j = i + l
        dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + acum[j] - acum[i]

print(dp[0][n])



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

INF = float('inf')
dp = [[INF] * (n+1) for _ in range(n+1)]

acum = [0] * (n+1)
for i, ai in enumerate(a):
    acum[i+1] += acum[i] + ai

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

for l in range(2, n+1):
    for i in range(n-l+1):
        j = i + l
        for k in range(i+1, j):
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + acum[j] - acum[i])

print(dp[0][n])

# Buggy version:
from itertools import accumulate
import sys
# python template for atcoder1
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

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

dp = [[float(0)]*N for _ in range(N)]
a_acc = [0]+list(accumulate(A))


def dfs(l, r):
    """
    List[l:r]
    """
    if dp[l][r-1] != float('inf'):
        return dp[l][r-1]
    if r-l == 1:
        dp[l][r-1] = 0
        return 0
    if r-l == 2:
        dp[l][r-1] = A[l]+A[r-1]
        return dp[l][r-1]
    else:
        dp[l][r-1] = min(dfs(l, v)+dfs(v, r)
                         for v in range(l+1, r))+a_acc[r]-a_acc[l]
        return dp[l][r-1]


def bfs():
    for d in range(2, N+1):
        for l in range(0, N-d+1):
            r = l + d
            #print("l,r->", l, r)
            tmp = float('inf')
            for m in range(l+1, r):
                tmp = min(tmp, dp[l][m-1]+dp[m][r-1])
            #print("tmp->", tmp)
            #print("acc->", a_acc[r]-a_acc[l])
            dp[l][r-1] = tmp+a_acc[r]-a_acc[l]


# print(a_acc)
bfs()
# print(dp)
print(dp[0][-1])


# Fixed version:
from itertools import accumulate
import sys
# python template for atcoder1
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

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

dp = [[float(0)]*N for _ in range(N)]
a_acc = [0]+list(accumulate(A))


def dfs(l, r):
    """
    List[l:r]
    """
    if dp[l][r-1] != float('inf'):
        return dp[l][r-1]
    if r-l == 1:
        dp[l][r-1] = 0
        return 0
    if r-l == 2:
        dp[l][r-1] = A[l]+A[r-1]
        return dp[l][r-1]
    else:
        dp[l][r-1] = min(dfs(l, v)+dfs(v, r)
                         for v in range(l+1, r))+a_acc[r]-a_acc[l]
        return dp[l][r-1]


def bfs():
    for d in range(2, N+1):
        for l in range(0, N-d+1):
            r = l + d
            #print("l,r->", l, r)
            tmp = float('inf')
            for m in range(l+1, r):
                tmp = min(tmp, dp[l][m-1]+dp[m][r-1])
            #print("tmp->", tmp)
            #print("acc->", a_acc[r]-a_acc[l])
            dp[l][r-1] = tmp+a_acc[r]-a_acc[l]


# print(a_acc)
bfs()
# print(dp)
ans = int(dp[0][-1])
print(ans)