标签:style color io os ar for 文件 sp c
一.试题
</pre><pre name="code" class="cpp">#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> using namespace std; #define N 105 //定义二维数组m[i][j]来记录i到j的合并过成中最少石子数目 int solve_min(int *p,int n) { int i,j,k,r,sum; int m[N][N]; memset(m,-1,sizeof(m)); for(i=1; i<=n; i++) //当一个单独合并时,m[i][i]设为0,表示没有石子 m[i][i]=0; for(i=1; i<n; i++) //当相邻的两堆石子合并时,此时的m很容易可以看出是两者之和 m[i][i+1]=p[i]+p[i+1]; for(r=3; r<=n; r++) //当相邻的3堆以及到最后的n堆时,执行以下循环 { for(i=1; i<=n-r+1; i++) { j=i+r-1; sum=0; for(k=i; k<=j; k++) //当i到j堆石子合并时最后里面的石子数求和得sum sum+=p[k]; m[i][j]=m[i+1][j]+sum; // 此时m[i][j]为i~j堆石子间以m[i][i]+m[i+1][j]+sum结果,这是其中一种可能,不一定是最优 for(k=i+1; k<j; k++) { int t=m[i][k]+m[k+1][j]+sum; if(t<m[i][j]) m[i][j]=t; } } } return m[1][n]; } int solve_max(int *p,int n) { int i,j,k,r,sum; int m[N][N]; memset(m,-1,sizeof(m)); for(i=1; i<=n; i++) m[i][i]=0; for(i=1; i<n; i++) m[i][i+1]=p[i]+p[i+1]; for(r=3; r<=n; r++) { for(i=1; i<=n-r+1; i++) { j=i+r-1; sum=0; for(k=i; k<=j; k++) sum+=p[k]; m[i][j]=m[i+1][j]+sum; for(k=i+1; k<j; k++) { int t=m[i][k]+m[k+1][j]+sum; if(t>m[i][j]) m[i][j]=t; } } } return m[1][n]; } int main() { int i,j,k,n,stone[N]; while(scanf("%d",&n)!=-1) { for(i=1; i<=n; i++) { scanf("%d",&stone[i]); } int mmin=solve_min(stone,n); int mmax=solve_max(stone,n); for(j=1; j<n; j++) { int t=stone[1]; for(k=1; k<n; k++) { stone[k]=stone[k+1]; } stone[n]=t; int tmin=solve_min(stone,n); int tmax=solve_max(stone,n); if(tmin<mmin) mmin=tmin; if(tmax>mmax) mmax=tmax; } printf("%d\n%d\n",mmin,mmax); } return 0; }
标签:style color io os ar for 文件 sp c
原文地址:http://blog.csdn.net/u011721440/article/details/39693627