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

题目描述 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.
时间: 2024-10-08 12:20:07

合并类动态规划——石子合并的相关文章

合并类动态规划,石子归并,合并石子解题报告

石子归并问题 1:任意版 有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为将的一堆石子的数量.设计一个算法,将这N堆石子合并成一堆的总花费最小(或最大). 此类问题比较简单,就是哈夫曼编码的变形,用贪心算法即可求得最优解.即每次选两堆最少的,合并成新的一堆,直到只剩一堆为止.证明过程可以参考哈夫曼的证明过程. 2.链式归并 问题描述 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=100).每堆沙子有一定的数量.现要将N堆沙子并成为一堆.归并的

动态规划—石子合并(直线和环)

先来看直线的: N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24) 1 2 3 4 => 1 2 7(7) => 3 7(10) =>

合并类动态规划——能量项链

能量项链 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(

动态规划思想:石子合并问题

描述:在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分. 贪心算法不能得到最优解,可惜了.首先我们可以把这么堆石子看成一列 如果N-1次合并的全局最优解包含了每一次合并的子问题的最优解,那么经这样的N-1次合并后的得分总和必然是最优的.因此我们需要通过动态规划算法来求出最优解. 在此我们假设有n堆石子,一字排开,合并相邻两堆的石子,

zjnu1181 石子合并【基础算法?动态规划】——高级

Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合并前对调一次相邻两堆石子的次序. 计算在上述条件下将n堆石子合并成一堆的最小得分. Input 输入数据共有二行,其中,第1行是石子堆数n≤100: 第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔. Output 输出合并的最小得分. Sample Input 3 2 5 1 Sample Out

石子合并 (动态规划)

一.试题 在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆.规定 每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 编一程序,由文件读入堆数N及每堆的石子数(≤20), ①选择一种合并石子的方案,使得做N-1次合并,得分的总和最小: ②选择一种合并石子的方案,使得做N-1次合并,得分的总和最大. 例如,所示的4堆石子,每堆石子数(从最上面的一堆数起,顺时针数)依 次为4594.则3次合并得分总和最小的方案:8+13+22=43 得分最大的

算法温习动态规划之石子合并问题

石子合并问题分为直线型和圆形: 直线型: 直线型狮子合并问题存在以下递推式: f[i][j]:表示从第i堆合并到底j堆,最少代价 f[i][j]=0;     i=j f[i][j]=min( f[i][k]+f[k+1][j]+sum(i,j));       i<=k<j; 这个问题比较好理解,根据递推式,我们的i要从高到底遍历,j要从低到高遍历 直线型代码如下: #include<iostream> #include<vector> using namespace

石子合并的动态规划问题

题目大概都是这样的: 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为 1  3  5  2 我们可以先合并1.2堆,代价为4,得到4 5 2 又合并 1,2堆,代价为9,得到9 2 ,再合并得到11,总代价为4+9+11=24,如果第二步

石子合并问题(直线版)

首先来个题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=737 有个更难的版本(不过很好玩):http://www.lydsy.com/JudgeOnline/problem.php?id=3229 题目: 石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价