P1880 [NOI1995]石子合并

题目描述

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

【思路】

区间DP

【核心思路】

又是围成一个圈

所以处理方式很显然

就是在原来的序列后面放一个和原来序列一样的序列就可以了

这样2-n+1区间就是存在的

而且是那1-n个数

就是起点不同而已

每次合并后的值等于原来合并的价值

加上

这次合并的石子数

如果只用一个二维数组f[i][j]的话显然是没有办法保存的

所以可以利用一个很优美的东西

前缀和

利用前缀和可以求出某个区间的石子数

也就是可以知道每次石子合并可以新得到的值

那么就可以只用f[i][j]来存i-j区间内

合并石子的最值就好了

【DP式】

DP方程式:

f1[i][j] = max(f1[i][j],f1[i][k] + f1[k + 1][j] + cost[i][j])

f2[i][j] = min(f2[i][j],f2[i][k] + f2[k + 1][j] + cost[i][j])

(一个求区间最大值,一个求区间最小值)

这个区间的最值就等于分成两个小区间合并起来之后的最值

【最终结果】

最后结果

自然是比较i-i + n - 1这个区间啦

因为圈不同于一条线的就是可以任选起点

所以要比较以每一个作为起点时的最值

输出就好了

【完整代码】

#include<iostream>
#include<cstdio> using namespace std;
const int Max = 206;
int f1[Max][Max];
int f2[Max][Max];
int a[Max];
int sum[Max];
int cost[Max][Max];
int main()
{
int n;
cin >> n;
for(register int i = 1;i <= n;++ i)
cin >> a[i],a[i + n] = a[i];
for(register int i = 1;i <= n * 2;++ i)
sum[i] = sum[i - 1] + a[i];
for(register int i = 1;i <= n * 2;++ i)
for(register int j = i;j <= n * 2;++ j)
cost[i][j] = sum[j] - sum[i - 1];
for(register int len = 1;len <= n;++ len)
{
for(register int i = 1;i + len - 1 <= n * 2;++ i)
{
int j = i + len - 1;
if(i != j)
f2[i][j] = 999999999;
for(register int k = i;k < j;++ k)
f1[i][j] = max(f1[i][j],f1[i][k] + f1[k + 1][j] + cost[i][j]),
f2[i][j] = min(f2[i][j],f2[i][k] + f2[k + 1][j] + cost[i][j]);
}
}
int M = 0;
int MM = 0x7fffffff;
for(register int i = 1;i <= n;++ i)
M = max(M,f1[i][i + n - 1]),
MM = min(MM,f2[i][i + n - 1]);
cout << MM << endl << M << endl;
return 0;
}

洛谷 P1880 [NOI1995]石子合并 题解的更多相关文章

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

    洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...

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

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

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

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

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

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

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

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

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

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

  7. 【区间dp】- P1880 [NOI1995] 石子合并

    记录一下第一道ac的区间dp 题目:P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include <iostream> ...

  8. P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]

    P1880 [NOI1995]石子合并 丢个地址就跑(关于四边形不等式复杂度是n方的证明) 嗯所以这题利用决策的单调性来减少k断点的枚举次数.具体看lyd书.这部分很生疏,但是我还是选择先不管了. # ...

  9. 区间DP小结 及例题分析:P1880 [NOI1995]石子合并,P1063 能量项链

    区间类动态规划 一.基本概念 区间类动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的那些元素合并而来由很大的关系.例如状态f [ i ][ j ],它表示以已合 ...

随机推荐

  1. Flanne

    容器面临的问题 物理机A上的应用A看到的IP地址是容器A的,是172.17.0.2,在物理机B上的应用B看到的IP地址是容器B的,不巧也是172.17.0.2,当它们都注册到注册中心的时候,注册中心就 ...

  2. Sqlserver 总结(2) 存储过程

    目录 写在前面 什么是存储过程 存储过程的优点 存储过程的分类 1.只返回单一记录集的存储过程 2.没有输入输出的存储过程 3.有返回值的存储过程 4.有输入参数和输出参数的存储过程 5.同时具有返回 ...

  3. Flutter Platform Channels

    Flutter Platform Channels(一) https://www.jianshu.com/p/33ac774f99b1 https://www.jianshu.com/p/c1e206 ...

  4. github-git clone 下载很慢的问题解决

    git clone下载很慢的问题: 下载到指定目录:git clone https://github.com/ChengWuOne/spring-cloud-demo.git D:/日常软件/GitH ...

  5. 【RAC】 RAC For W2K8R2 安装--共享磁盘的配置(三)

    [RAC] RAC For W2K8R2 安装--共享磁盘的配置(三) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学 ...

  6. Oracle间隔(interval)分区

    (一)什么是间隔分区 间隔分区是Oracle 11.1引入的新功能,通过该功能,可以在输入相应分区的数据时自动创建相应的分区.在没有间隔分区技术之前,DBA通常会创建一个maxvalue分区以避免OR ...

  7. 基于gtk的imshow:用stb_image读取图像并用gtk显示

    在前面一篇,已经能够基于gtk读取图像并显示.更前面的一篇:基于GDI的imshow:使用stb_image读取图像并修正绘制,通过stb_image读取图像并通过GDI显示图像,实现了一个imsho ...

  8. web之表单form

    表单是我们平常编写Web应用常用的工具,表单(<form>)用来收集用户提交的数据,发送到服务器.比如,用户提交用户名和密码,让服务器验证,就要通过表单.表单是一个包含表单元素或控件的区域 ...

  9. mysqlbinlog 恢复数据到任意时间点

    创建表,插入数据. ``` mysql> create database binlog; mysql> create table bt(id int); mysql> insert ...

  10. jquery 插入节点

    往某个元素内部的结尾添加 append() appendTo() append() <body> <button id="bt1">点击通过jQuery的a ...