题目连接:
https://www.acwing.com/problem/content/284/
思路:首先你需要知道最后一次合并石子,肯定是左右俩堆的合并,所以可以想到区间dp , f[i][j]表示石子i到j合并成一堆的集合
之后就是对区间的划分了,如下图所示
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int N= 310;
int a[N],s[N];
int f[N][N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<= n;i++){
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];
}
memset(f,INF ,sizeof f);
for(int i =1 ;i < N;i++) f[i][i]= 0;
for(int len = 2;len <= n; len ++ ){
for(int l = 1; l + len - 1 <= n;l++){
int r = l + len -1;
for(int k = l; k < r; k ++ ){
f[l][r] = min(f[l][r],f[l][k]+ f[k+1][r]+s[r]-s[l-1]);
}
}
}
printf("%d\n",f[1][n]);
}