码迷,mamicode.com
首页 > 其他好文 > 详细

合并类动态规划——石子合并

时间:2015-08-18 18:42:40      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

 题目描述 Description
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
 输入输出格式 Input/output
输入格式:
数据的第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.

 

合并类动态规划——石子合并

标签:

原文地址:http://www.cnblogs.com/zqzxwdm/p/4739983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!