include[HTML_REMOVED]
int min(int a, int b) {
return a < b ? a : b;
}
int main() {
int n;
int a[301];
scanf(“%d”, &n);
for(int i = 1; i <= n; i++) scanf(“%d”, a + i);
int dp[301][301] = {0}; // dp[i][j] 表示区间 i:j 的最小耗费
int sum[301] = {0}; // 前缀和数组
// 计算前缀和
for(int i = 1; i <= n; i++) {
sum[i] = sum[i-1] + a[i];
}
// 初始化 dp 数组
for(int i = 1; i <= n; i++) {
dp[i][i] = 0; // 单个石子的合并代价为 0
}
// 动态规划
for(int len = 2; len <= n; len++) { // 枚举区间长度
for(int i = 1; i <= n - len + 1; i++) { // 枚举区间起点
int j = i + len - 1; // 区间终点
dp[i][j] = 0x7fffffff; // 初始化为无穷大
for(int k = i; k < j; k++) { // 枚举分割点
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]);
}
}
}
printf("%d\n", dp[1][n]); // 输出合并整个区间的最小代价
return 0;
}