一.试题
在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆。规定
每次仅仅能选相邻的两堆合并成新的一堆,并将新的一堆的石子数。记为该次合并的得分。
编一程序。由文件读入堆数N及每堆的石子数(≤20)。
①选择一种合并石子的方案,使得做N-1次合并,得分的总和最小。
②选择一种合并石子的方案,使得做N-1次合并。得分的总和最大。

比如,所看到的的4堆石子,每堆石子数(从最上面的一堆数起。顺时针数)依
次为4594。则3次合并得分总和最小的方案:8+13+22=43
得分最大的方案为:14+18+22=54



</pre><pre name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
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<n; i++) //当相邻的两堆石子合并时。此时的m非常easy能够看出是两者之和
m[i][i+1]=p[i]+p[i+1];
for(r=3; r<=n; r++) //当相邻的3堆以及到最后的n堆时,运行下面循环
{
for(i=1; i<=n-r+1; i++)
{
j=i+r-1;
sum=0;
for(k=i; k<=j; k++) //当i到j堆石子合并时最后里面的石子数求和得sum
sum+=p[k];
m[i][j]=m[i+1][j]+sum;
// 此时m[i][j]为i~j堆石子间以m[i][i]+m[i+1][j]+sum结果。这是当中一种可能,不一定是最优
for(k=i+1; k<j; k++)
{
int t=m[i][k]+m[k+1][j]+sum;
if(t<m[i][j])
m[i][j]=t;
}
}
}
return m[1][n];
}
int solve_max(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;
for(i=1; i<n; i++)
m[i][i+1]=p[i]+p[i+1];
for(r=3; r<=n; r++)
{
for(i=1; i<=n-r+1; i++)
{
j=i+r-1;
sum=0;
for(k=i; k<=j; k++)
sum+=p[k];
m[i][j]=m[i+1][j]+sum;
for(k=i+1; k<j; k++)
{
int t=m[i][k]+m[k+1][j]+sum;
if(t>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<n; j++)
{
int t=stone[1];
for(k=1; k<n; k++)
{
stone[k]=stone[k+1];
}
stone[n]=t;
int tmin=solve_min(stone,n);
int tmax=solve_max(stone,n);
if(tmin<mmin)
mmin=tmin;
if(tmax>mmax)
mmax=tmax;
}
printf("%d\n%d\n",mmin,mmax);
}
return 0;
}

石子合并 (区间DP)的更多相关文章

  1. 洛谷 P1880 [NOI1995] 石子合并(区间DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...

  2. 石子合并 区间dp模板

    题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合 ...

  3. HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结

    题意:给定一个字符串 输出回文子序列的个数    一个字符也算一个回文 很明显的区间dp  就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...

  4. 石子合并 区间DP模板题

    题目链接:https://vjudge.net/problem/51Nod-1021 题意 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石 ...

  5. 洛谷 P1080 石子合并 ( 区间DP )

    题意 : 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成1堆 ...

  6. 石子合并——区间dp

    石子合并(3种变形) <1> 题目: 有N堆石子排成一排(n<=100),现要将石子有次序地合并成一堆,规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数,记为改次合并的得分, ...

  7. 洛谷P1880 石子合并(环形石子合并 区间DP)

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  8. HRBUST - 1818 石子合并 区间dp入门

    有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...

  9. HDU 3506 (环形石子合并)区间dp+四边形优化

    Monkey Party Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Tot ...

  10. P1880 [NOI1995]石子合并 区间dp+拆环成链

    思路 :一道经典的区间dp  唯一不同的时候 终点和起点相连  所以要拆环成链  只需要把1-n的数组在n+1-2*n复制一遍就行了 #include<bits/stdc++.h> usi ...

随机推荐

  1. (noip模拟十七)【BZOJ3930】[CQOI2015]选数-容斥水法

    Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...

  2. PHP SOAP模块的使用方法:NON-WSDL模式

    PHP SOAP扩展可以帮助我们很轻松的实现web service服务,在PHP的SOAP扩展中主要有两种操作模式:WSDL模式和NON-WSDL模式,前者通过使用WSDL文件名作为参数,并从 WSD ...

  3. 什么是面向对象以及其意义,prototpye原型

    什么是面向对象: 使用对象时,只关注对象提供的功能,不关注其内部的细节 例如:jquery 什么是对象: 对象是一个整体对外提供一些操作,比如 收音机 面向对象编程OOP的特点: 1.抽象:把主要的特 ...

  4. 【BZOJ 1406】 [AHOI2007]密码箱

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] \(x^2%n=1\) \(x^2-1 = k*n\) \((x+1)*(x-1) % n == 0\) 设\(n=a*b\) 对于 ...

  5. 【codeforces 239B】Easy Tape Programming

    [题目链接]:http://codeforces.com/contest/239/problem/B [题意] 给你一个长度为n的字符串,只包括'<">'以及数字0到9; 给你q ...

  6. linux的一页是多大

    命令 getconf PAGESIZE 结果为4096,即一页=4096字节=4KB(注意是Byte,1B=8bit) 在使用mmap映射函数时,它的实际映射单位也是以页为单位的,即不过我们把MAP_ ...

  7. 埃及分数 迭代加深搜索 IDA*

    迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...

  8. Obfuscating computer code to prevent an attack

    A method and system for obfuscating computer code of a program to protect it from the adverse effect ...

  9. java用freemarker实现导出word----包含图片

    分为以下三个步骤: 1.先制作word模板 2.将该文档另存为 xml 文件 3.打开xml 文件 将对应的字段替换,比如 4.将xml文件保存成ftl格式的文档 5.相应的代码: package o ...

  10. Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(二)__原理分析

    前置文章: <Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(一)__使用具体解释> 转载请务必注明出处:http://b ...