洛谷P1880 石子合并 纪中2119. 环状石子归并

洛谷传送门

题目描述1

在一个圆形操场的四周摆放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

(File IO): input:stone.in output:stone.out

时间限制: 1000 ms  空间限制: 262144 KB  具体限制  

Goto ProblemSet

题目描述2

在一个环状跑道上摆放着N堆石子,现在要将所有的石子有次序地合并成一堆。规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。问最少的总得分是多少?

输入

第一行为石子堆数N。
从第2行到第N + 1行,每行一个正整数。第i个数表示第i堆石子的石子数。

输出

在第一行输出一个整数,表示最少的总得分。

样例输入

4
4
5
9

样例输出

43 

数据范围限制

在40%的数据中,1 ≤ N ≤ 100
在60%的数据中,1 ≤ N ≤ 200
在100%的数据中,1 ≤ N ≤ 2000
保证输入数据中每堆石子的石子数不超过10000

Solution

此题为区间DP+四边形不等式

这是我第一次见到区间DP

洛谷上既要求最大值,也要求最小值,(多写几句话的事~)但是数据范围最大只有100

jzoj上就恶心了,虽然只要求最小值,但是数据范围最大为2000!

Algorithm1

标准的区间DP

由于这是环形的,所以要把整个跑道复制一遍

可以在输入的同时操作

(约定:s[i]表示第i(0~n-1)堆石子的数量)

for(int i=;i<n;i++) cin>>s[i],s[i+n]=s[i];

做DP前要先弄清楚“阶段”,“状态”,“决策”;

由于首先要合并两堆,再在两堆的基础上合并三堆,再在三堆的基础上合并四堆……以此类推。

并且,每次要选相邻的两堆合并(这就是为什么不能像“合并果子那样使用贪心”)

所以,每一个阶段就是合并去=的区间长度 len

这个len在循环的最外层,从2至n(最少合并2堆)

其次是状态

状态即为最初的第l堆石子和第r堆石子被合并,

同时l~r这段区间的长度为阶段——len。

所以我们要枚举的状态就是左端点

范围:左极限为0,右极限为右端点<n

最内层是决策

顾名思义:

就是决定当前应该选哪两堆来合并

对于目前长度为len的区间[l,r)

可以选出一个中间点k∈[l,r)

表示先合并了[l,k],再合并[k+1,r)

所以决策就是中间点k

同时还要计算合并这两堆石子所需要的体力(即为两堆石子的石子数量之和)

可以使用前缀和计算

Code1

洛谷Code

 #include<iostream>//不想OI一场空,千万别用万能头
#include<algorithm>//快排sort()
#include<cstdio>//能不用cin就不用
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#define IL inline
using namespace std; int s[],n,minn=0x3f3f3f3f,maxn;
int dpmin[][],dpmax[][];
int sum[];
int main()
{
cin>>n;
memset(dpmin,0x3f,sizeof(dpmin));
for(int i=;i<n;i++) cin>>s[i],s[i+n]=s[i];
for(int i=;i<*n;i++)
dpmin[i][i]=;
sum[]=s[];
for(int i=;i<*n;i++) sum[i]=sum[i-]+s[i];
for(int len=;len<=n;len++)
{
for(int l=;l+len-<*n;l++)
{
for(int k=l;k<l+len-;k++)
dpmin[l][l+len-]=min(dpmin[l][l+len-],dpmin[l][k]+dpmin[k+][l+len-]),
dpmax[l][l+len-]=max(dpmax[l][l+len-],dpmax[l][k]+dpmax[k+][l+len-]);
dpmin[l][l+len-]+=sum[l+len-]-sum[l-];
dpmax[l][l+len-]+=sum[l+len-]-sum[l-];
}
}
for(int i=;i<n;i++)
minn=min(minn,dpmin[i][i+n-]),maxn=max(maxn,dpmax[i][i+n-]);
cout<<minn<<endl<<maxn;
return ;
}

纪中Code1(70分)

 #include<iostream>//不想OI一场空,千万别用万能头
#include<algorithm>//快排sort()
#include<cstdio>//能不用cin就不用
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#define IL inline
using namespace std; int s[],n,minn=0x3f3f3f3f;
int f[][];
int sum[];
IL int read()
{
int res=;
char ch=getchar();
while(ch<''||ch>'')
ch=getchar();
while(ch>=''&&ch<='')
res=(res<<)+(res<<)+(ch^),ch=getchar();
return res;
} int main()
{
// freopen("stone.in","r",stdin);
// freopen("stone.out","w",stdout);
n=read();
memset(f,0x3f,sizeof(f));
for(int i=;i<=n;i++) s[i]=read(),s[i+n]=s[i];
for(int i=;i<=*n;i++)
f[i][i]=,sum[i]=sum[i-]+s[i];
for(int len=;len<=n;len++)
{
for(int l=;l+len-<=*n;l++)
{
for(int k=l;k<l+len-;k++)
f[l][l+len-]=min(f[l][l+len-],f[l][k]+f[k+][l+len-]);
f[l][l+len-]+=sum[l+len-]-sum[l-];
}
}
for(int i=;i<=n;i++)
minn=min(minn,f[i][i+n-]);
cout<<minn;
return ;
}

纪中Code1

为什么折叠?

纪中此题的范围是2000,要用到四边形不等式优化成n2才能过……毒瘤呀

Attention1

所有数组都要开两倍大——这是环状变链状。

Algorithm2

四边形不等式

对于一个函数f(i,j),有四个值a<=b<c<=d

使得f(a,b)+f(c,d)<f(a,c)+f(b,d)

那么这个函数满足四边形不等式

可以放到决策k时使用

至于证明嘛……打表证吧

Impression

2019-08-22 11:51:55

与此同时……

哪个人知道我们听不懂今天的讲课会都回来,故意放了比赛???

洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并的更多相关文章

  1. 纪中21日T3 2118. 【2016-12-30普及组模拟】最大公约数

    纪中21日T3 2118. 最大公约数 (File IO): input:gcd.in output:gcd.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto ...

  2. 洛谷 P1880 [NOI1995]石子合并 题解

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

  3. [洛谷P1880][NOI1995]石子合并

    区间DP模板题 区间DP模板Code: ;len<=n;len++) { ;i<=*n-;i++) //区间左端点 { ; //区间右端点 for(int k=i;k<j;k++) ...

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

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

  5. 洛谷P1880 [NOI1995] 石子合并 [DP,前缀和]

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

  6. 洛谷 P1880 [NOI1995]石子合并

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

  7. 纪中21日c组模拟赛

    AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL 题解传送 T1  ...

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

    嗯... 题目链接:https://www.luogu.org/problem/P1880 这道题特点在于石子是一个环,所以让a[i+n] = a[i](两倍长度)即可解决环的问题,然后注意求区间最小 ...

  9. 纪中21日c组T1 1575. 二叉树

    1575. 二叉树 (File IO): input:tree.in output:tree.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制   Goto Probl ...

随机推荐

  1. Java:多线程概述与创建方式

    目录 Java:多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start()和run() 实现Runnable接口 实现Callable接口 创建方 ...

  2. Comet OJ Contest #0 解方程(暴力)

    题意: 给定自然数n,求满足$\displaystyle \sqrt{x-\sqrt{n}}=\sqrt{z}-\sqrt{y}$的x,y,z,输出解的个数以及所有解 xyz的和 n<=1e9, ...

  3. 实现理论上无tps上限的分布式压测(基于Jmeter+InfluxDB+Grafana+Spring Boot)

    JMeter自身带有Master-Slave压测框架,对于并发量不是很高的压力情况下(比如tps低于5000),该方案是可行的,并且使用起来非常方便,只要在配置文件或者命令行工具的参数做一些补充,即可 ...

  4. JMeter+Grafana+Influxdb搭建可视化性能测试监控平台(待继续完善。。。)

    influxdb下载.安装.配置.启动 InfluxDB是一个当下比较流行的时序数据库,InfluxDB使用 Go 语言编写,无需外部依赖,安装配置非常方便,适合构建大型分布式系统的监控系统. 下载: ...

  5. python使用turtle库绘制奥运五环

    效果图: #奥运五环 import turtle turtle.setup(1.0,1.0) #设置窗口大小 turtle.title("奥运五环") #蓝圆 turtle.pen ...

  6. Java开发最佳实践(二) ——《Java开发手册》之"异常处理、MySQL 数据库"

    二.异常日志 (一) 异常处理 (二) 日志规约 三.单元测试 四.安全规约 五.MySQL数据库 (一) 建表规约 (二) 索引规约 (三) SQL语句 (四) ORM映射 六.工程结构 七.设计规 ...

  7. df du 文件空间管理 命令

     df  可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力. du 可以查看文件及文件夹的大小.     df:常用   df -h    以易读形式显示 磁盘空间 linux ...

  8. iptables之路由网关共享上网/端口映射

    linux-A 主机配置eth0即可: [root@linux-A ~]# ifconfig eth0|sed -n '2p' inet addr:192.168.20.3 Bcast:192.168 ...

  9. Qt Python Scriptable Application

    Qt Python Scriptable Application eryar@163.com Abstract. Python and C++ are in many ways as differen ...

  10. 使用Vue.prototype在vue中注册和使用全局变量

    在main.js中添加一个变量到Vue.prototype Vue.prototype.$appName = 'My App' 这样 $appName 就在所有的 Vue 实例中可用了,甚至在实例被创 ...