【石子合并】
在一个直线操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
【输入文件】
包含两行,第1 行是正整数n(1<=n<=100),表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。
【输出文件】
输出两行。
第1 行中的数是最小得分;第2行中的数是最大得分。
【输入样例】
4
44 5 9
【输出样例】
43
54
#include
#include
#define max 9999
int a[101];
int dp_min[101][101];
int dp_max[101][101];
int sum[101][101];
int main()
{
int n;
scanf("%d",&n);
int i;
int j,k;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(sum,0,sizeof(sum));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i<=j)
{
for(k=i;k<=j;k++)
{
sum[i][j]+=a[k];
}
}
else
{
for(k=j;k<=i;k++)
{
sum[i][j]+=a[k];
}
}
}
}
memset(dp_max,0,sizeof(dp_max));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
dp_min[i][j]=max;
}
}
for(j=1;j<=n;j++)
{
dp_min[j][j]=0;
}
int len;
for(len=1;len<=n;len++)
for(i=1;i<=n-len+1;i++)
{
j=i+len-1;
for(k=i;k
dp_min[i][k]+dp_min[k+1][j]+sum[i][j])
{
dp_min[i][j]=dp_min[i][k]+dp_min[k+1][j]+sum[i][j];
}
if(dp_max[i][j]