洛谷 P1880 石子合并

来源:互联网 发布:phantomjs pdf python 编辑:程序博客网 时间:2024/05/16 10:29

题目描述

在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入输出格式

输入格式:
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

输出格式:
输出共2行,第1行为最小得分,第2行为最大得分.

输入输出样例

输入样例#1:
4
4 5 9 4
输出样例#1:
43
54

分析:先把环变为线。就是把数列copy一遍。然后我们知道,
设f[i,j]为和并i–j的代价,有
f[i,j]=max(f[i,j],f[i,k]+f[k+1,j]+sum(a[i]~a[j]));
(其他区间和并成这两个区间的代价+这两个区间和并成一个区间的代价)

代码:

var a,sum:array [0..201] of longint; f,f1:array [1..201,1..201] of longint; n,m,i,j,q,ma,mi,k:longint;function max(x,y:longint):longint; begin  if x>y then exit(x)         else exit(y); end;function min(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 do  sum[i]:=a[i]+sum[i-1]; mi:=maxlongint; for j:=1 to 2*n do  for i:=1 to 2*n-j+1 do   begin    q:=i+j-1;    if q=i then     begin      f[i,q]:=0;      f1[i,q]:=0;      continue;     end;    f1[i,q]:=maxlongint;    for k:=i to q-1 do    begin     f[i,q]:=max(f[i,k]+f[k+1,q]+sum[q]-sum[i-1],f[i,q]);     f1[i,q]:=min(f1[i,k]+f1[k+1,q]+sum[q]-sum[i-1],f1[i,q]);    end;   if j=n then    begin     if f[i,q]>ma then ma:=f[i,q];     if f1[i,q]<mi then mi:=f1[i,q];    end;   end; writeln(mi); writeln(ma);end.
0 0
原创粉丝点击