数据范围
对于 20%的数据,n=5
对于 60%的数据,n<=80
对于 100%的数据,n<=400
60分的做法:与石子合并一样,枚举起点,终点,第一个断点,第二个断点。时间复杂度O(n^4)。
100分做法:
用另一个数组f2[i][j]来优化,f2[][]是合并两堆最小(不过要用f[][]来更新),就可以降到O(n^4)。
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#define LL long long
#define M 1000000000
using namespace std;
int n,a[409];
int f[409][409],f2[409][409],s[409];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=M,f2[i][j]=M;
for(int i=n;i;i--)
{
f[i][i]=0;
f[i][i+2]=s[i+2]-s[i-1];
for(int j=i+3;j<=n;j++)
{
for(int k=i;k<j;k++)
f2[i][j]=min(f2[i][j],f[i][k]+f[k+1][j]);
for(int k=i;k<j;k++)
f[i][j]=min(f[i][j],min(f[i][k]+f2[k+1][j],f2[i][k]+f[k+1][j])+s[j]-s[i-1]);
}
}
printf("%d",f[1][n]);
return 0;
}