// 引入万能头文件,包含所有常用的STL库(竞赛场景常用)
#include<bits/stdc++.h>
// 使用std命名空间,避免重复书写std::前缀
using namespace std;

// 定义常量:N为区间最大长度,MAX为代价的初始极大值(用于求最小值的初始化)
const int N=400,MAX=1e9+10;

// 全局变量声明
int n;                  // n:表示要合并的区间总数/元素个数
int dp[N][N];           // dp[i][j]:动态规划数组,存储合并区间[i, j]的最小代价
int m[N];               // m数组:存储每个子区间的基础数值(如石子合并问题中的石子数量)
int sum_m[N];           // sum_m数组:m数组的前缀和,用于快速计算区间[i, j]的数值总和

// 核心求解函数:通过动态规划计算合并所有区间的最小代价
void solve(){
    // 枚举区间长度,从2开始(长度为1的区间无需合并,代价为0)
    for(int len=2;len<=n;len++){
        // 枚举区间的起点i,确保终点j=i+len-1不超过n
        for(int i=1;i<=n-len+1;i++){
            // 计算区间的终点j
            int j=i+len-1;
            // 初始化dp[i][j]为极大值,后续通过状态转移更新最小值
            dp[i][j]=MAX;
            // 计算区间[i, j]的数值总和(利用前缀和快速求解)
            int value=sum_m[j]-sum_m[i-1];
            // 枚举区间分割点k,将[i,j]拆分为[i,k]和[k+1,j]两部分
            for(int k=i;k<=j-1;k++){
                // 状态转移方程:合并[i,j]的最小代价 = min(当前值, 合并[i,k]的代价 + 合并[k+1,j]的代价 + 本次合并的基础代价)
                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+value);
            }
        }
    }
    // 输出合并整个区间[1,n]的最小代价
    cout<<dp[1][n]<<endl;
}

// 主函数:程序入口,负责输入数据、初始化并调用求解函数
int main(){
    // 关闭cin与stdio的同步,加速输入(竞赛常用优化)
    ios::sync_with_stdio(false);
    // 解绑cin和cout,避免cout刷新导致cin变慢
    cin.tie(0);
    
    // 输入区间总数n
    cin>>n;
    // 输入每个子区间的基础数值,并计算前缀和
    for(int i=1;i<=n;i++){
        cin>>m[i];
        // 前缀和公式:sum_m[i] = 前i-1项和 + 第i项
        sum_m[i]=sum_m[i-1]+m[i];
    }
    
    // 调用求解函数计算并输出结果
    solve();

    return 0;
}