一.试题
在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆。规定
每次仅仅能选相邻的两堆合并成新的一堆,并将新的一堆的石子数。记为该次合并的得分。
编一程序。由文件读入堆数N及每堆的石子数(≤20)。
①选择一种合并石子的方案,使得做N-1次合并,得分的总和最小。
②选择一种合并石子的方案,使得做N-1次合并。得分的总和最大。
比如,所看到的的4堆石子,每堆石子数(从最上面的一堆数起。顺时针数)依
次为4594。则3次合并得分总和最小的方案:8+13+22=43
得分最大的方案为:14+18+22=54
在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆。规定
每次仅仅能选相邻的两堆合并成新的一堆,并将新的一堆的石子数。记为该次合并的得分。
编一程序。由文件读入堆数N及每堆的石子数(≤20)。
①选择一种合并石子的方案,使得做N-1次合并,得分的总和最小。
②选择一种合并石子的方案,使得做N-1次合并。得分的总和最大。
比如,所看到的的4堆石子,每堆石子数(从最上面的一堆数起。顺时针数)依
次为4594。则3次合并得分总和最小的方案:8+13+22=43
得分最大的方案为:14+18+22=54
#include#include #include #include #include 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 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 mmax) mmax=tmax; } printf("%d\n%d\n",mmin,mmax); } return 0;}