题目描述
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
输入输出格式
输入格式:
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式:
输出共2行,第1行为最小得分,第2行为最大得分.
输入输出样例
输入样例#1:
4
4 5 9 4
输出样例#1:
43
54
#include<iostream>
#include<cstring>
using namespace std;
int s[201],f[201][201],ff[201][201],a[201];
int main()
{ int maxx=0,minn=0xfffffff;
int n;
cin>>n;
int nn=2*n-1;
for (int i=1;i<=n;++i)
{
cin>>a[i];
}
for (int l=1;l<=n;++l)
{ memset(s,0,sizeof(s));
for (int m=1;m<=n;++m)
{ int b=l+m-1;
if (l+m-1>n)
b=b%n;
s[m]=s[m-1]+a[b];
}
memset(f,0,sizeof(f));
memset(ff,127/3,sizeof(ff));
for (int i=1;i<=nn;++i)
ff[i][i]=0;
for (int i=n-1;i>=1;i--)
for (int j=i+1;j<=n;j++)
for (int k=i;k<=j-1;k++)
{
f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
ff[i][j]=min(ff[i][j],ff[i][k]+ff[k+1][j]+s[j]-s[i-1]);
}
minn=min(minn,ff[1][n]);
maxx=max(maxx,f[1][n]);
}
cout<<minn<<endl;
cout<<maxx;
}