注:图中椭圆代表以左边那堆石子的最后一个来划分 右边至少是1堆 所以左边最多j-1
图中公式代表两堆石子合并时所使用的代价
#include<bits/stdc++.h>
using namespace std;
const int N=310;
int n;
int s[N];
int f[N][N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&s[i]),s[i]+=s[i-1];//输入数据顺便求出前缀和
for(int len=2;len<=n;len++){// 枚举长度 长度为1时消耗为0
for(int i=1;i+len-1<=n;i++){//枚举左端点 条件为右端点小于等于长度
int j=i+len-1;//左端点的位置
f[i][j]=1e8;//因为要比较一轮取出最小值 所以给它赋个大点的值
for(int k=1;k<j;k++){//用k来划分每种情况 最后取出最小的 执行结束后增加一个长度继续执行
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
}
}
}
cout<<f[1][n]<<endl;//由几何的定义可知f[1][n]代表将1到n合并成一堆的最小值
return 0;
}