在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
/*
圆的话就用2*n-1,即只有n种情况;
*/
#include <iostream>
using namespace std;
#include <cstring>
#include <algorithm>
const int INF=(1<<31)-1;
int s[201],d[201][201],b[201][201],a[101];
int main(int argc, char *argv[])
{
int i,j,k,n,r,t,t1,m;
cin>>n; s[0]=0;
memset(d,0,sizeof(d)); memset(b,0,sizeof(b));
for(i=1;i<=n;i++) {cin>>a[i]; s[i]=s[i-1]+a[i];}
for(i=1;i<n;i++) s[n+i]=s[n+i-1]+a[i]; m=n,n=2*n-1;
for(r=2;r<=n;r++)
for(i=1;i<=n-r+1;i++)
{j=i+r-1; t=INF; t1=0;
for(k=i;k<=i+r-2;k++)
t= min(t,d[i][k]+d[k+1][j]+s[j]-s[i-1]), t1= max(t1,b[i][k]+b[k+1][j]+s[j]-s[i-1]);
d[i][j]=t; b[i][j]=t1;
}
t=INF; t1=0;
for(i=1;i<=m;i++)
{
if(t>d[i][m+i-1]) t=d[i][m+i-1];
if(t1<b[i][m+i-1]) t1=b[i][m+i-1];
}
if(m==1) t=a[1],t1=a[1];
cout<<t<<endl<<t1<<endl;
return 0;
}
1209

被折叠的 条评论
为什么被折叠?



