洛谷 P1880 [NOI1995]石子合并 题解
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]石子合并 题解的更多相关文章
- 洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并
洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...
- 洛谷 P1880 [NOI1995] 石子合并(区间DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...
- [洛谷P1880][NOI1995]石子合并
区间DP模板题 区间DP模板Code: ;len<=n;len++) { ;i<=*n-;i++) //区间左端点 { ; //区间右端点 for(int k=i;k<j;k++) ...
- 洛谷P1880 [NOI1995] 石子合并 [DP,前缀和]
题目传送门 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆 ...
- 洛谷 P1880 [NOI1995]石子合并
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- 洛谷 P1880 [NOI1995]石子合并(区间DP)
嗯... 题目链接:https://www.luogu.org/problem/P1880 这道题特点在于石子是一个环,所以让a[i+n] = a[i](两倍长度)即可解决环的问题,然后注意求区间最小 ...
- 【区间dp】- P1880 [NOI1995] 石子合并
记录一下第一道ac的区间dp 题目:P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include <iostream> ...
- P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]
P1880 [NOI1995]石子合并 丢个地址就跑(关于四边形不等式复杂度是n方的证明) 嗯所以这题利用决策的单调性来减少k断点的枚举次数.具体看lyd书.这部分很生疏,但是我还是选择先不管了. # ...
- 区间DP小结 及例题分析:P1880 [NOI1995]石子合并,P1063 能量项链
区间类动态规划 一.基本概念 区间类动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的那些元素合并而来由很大的关系.例如状态f [ i ][ j ],它表示以已合 ...
随机推荐
- 两台Windows的 IIS 应用站点 基于NLB + ARR 实现双机热备和负载
IIS负载均衡中我们使用微软的ARR,但提到网站的高可用性,ARR只能做请求入口的消息分发服务,这样如果我们的消息分发服务器给down掉啦,那么做再多的应用服务集群也都枉然. 这里我们主要针对解决这一 ...
- Hibernate的关联映射--一对多、
这是我 1 单向一对多: 实体类:(课程类)Grade与(学生类)Student的一对多关系 学生类: public class Student implements java.io.Serializ ...
- eclipse中启动tomcat后, 无法访问localhost:8080
问题: 今天老师讲了Servlet路径问题, 做了个测试在eclipse中启动tomcat后,在浏览器地址栏输入 http://localhost8080无法访问, 提示404错误, 正常情况是可以访 ...
- DOS之del命令
基本 del命令是用来删除一个或多个文件的,删除文件夹的话还要用rd命令. 举个栗子: 例如我们要删除C盘中的a.txt,我们就可以 del a.txt 也可以同时删除多个,用空格,逗号或分号分开文件 ...
- log4j使用指北
背景 工作一直使用日志组件,但是配置却一直看的糊里糊涂的,只记得个日志级别,其他的都不太理解,例如,一个页面日志太多,怎么样能单独打印?所以就找机会整理了一下. 本文参考:https://www.cn ...
- python基础知识和练习代码
1.编译:将高级语言源代码转换成目标代码(机器语言),程序便可运行. 好处:目标代码执行速度更快:目标代码在相同操作系统上使用灵活. 2.解释:将高级语言源代码逐条转换成目标代码同时逐条执行,每次 ...
- 常用的User-Agent
window.navigator.userAgent 1) ChromeWin7:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTM ...
- Android-----Intent通过startActivityForResult(Intent intent , int 标志符)启动新的Activity
我们都了解使用 startActivity(intent) 新的activity只能传递数据,却无法返回数据,返回新activity返回的数据我们可以替换startActivityForResult( ...
- Java 单例类
单例类:该类只能创建一个实例,或者说内存中只有一个实例,该类的对象引用的都是这个实例. 示例: package my_package; //定义一个单例类 class Singleton{ //使用一 ...
- WPF应用打包流程
1,安装工程模板插件Microsoft Visual Studio Installer Projects https://marketplace.visualstudio.com/items?item ...