题目描述 Description
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
输入输出格式 Input/output
输入格式:
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式:
输出共2行,第1行为最小得分,第2行为最大得分.
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式:
输出共2行,第1行为最小得分,第2行为最大得分.
输入输出样例 Sample input/output
样例测试点#1
输入样例:
4
4 5 9 4
输出样例:
43
54
来源:NOI 1996
代码:
var n,i,j,k,l,minf,maxf:longint; a,s:array[0..300] of longint; f:array[1..300,1..300] of longint; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; begin readln(n); for i:=1 to n do begin read(a[i]); a[i+n]:=a[i]; end; for i:=1 to 2*n-1 do s[i]:=s[i-1]+a[i]; for l:=2 to n do //枚举可能的长度 for i:=1 to 2*n-l do //环形扩展到链 begin j:=i+l-1; f[i,j]:=maxlongint; for k:=i to j-1 do f[i,j]:=min(f[i,j], f[i,k]+f[k+1,j]+s[j]-s[i-1]); end; minf:=maxlongint; for i:=1 to n do minf:=min(minf,f[i,i+n-1]); //求出最小的值 fillchar(f,sizeof(f),0); for l:=2 to n do for i:=1 to 2*n-1 do begin j:=i+l-1; f[i,j]:=0; for k:=i to j-1 do f[i,j]:=max(f[i,j], f[i,k]+f[k+1,j]+s[j]-s[i-1]); end; maxf:=0; for i:=1 to n do maxf:=max(maxf,f[i,i+n-1]); writeln(minf); writeln(maxf); end.