AcWing 1068. 环形石子合并(环形区间DP)
AcWing 1068. 环形石子合并(环形区间DP)
- 一、问题
- 二、思路
- 三、代码
一、问题
二、思路
在讲解这道题之前,我们需要先掌握线性的区间DP问题,如果对于线性区间DP的解决方式还不了解的话,建议先看一下这篇文章:石子合并(区间DP)
那么在了解了线性石子合并问题后,我们现在只剩下了一个难点:如何将环形转化为线性。
我们看下面图:
如果我们想要合并A和B的话,我们就在两堆石子之前连接一条线,那么当我们将这一圈石子合并为1堆的时候,情况如下图所示:
而这恰好就相当于一个线性的石子围成了一个圈,只不过我们的合并方式不同,最终剩下的缺口也不同。
那么我们就可以去枚举每一个缺口,展开为线性,最终在这么多种情况中选出一个最大的。
但是我们发现,我们的缺口有n个,那么这就说明,我们要在之前的区间DP的时间复杂度上再乘上一个n。
很显然这样的做法是不太高效的。
那么怎么办呢?
我们接着看下面这个图:
我们发现我们把这个字符串写两遍,这样我们就能在这个2n长度的石子中找到我们枚举的情况。
那么我们就在这个2n长度的石子中进行合并。
按照我们之前区间DP的状态定义,我们令 f [ l ] [ r ] f[l][r] f[l][r]表示将区间l到r内的石子合并为1堆所需要的最小值。
我们只需要去枚举所有的长度为n的f[l][r],然后取出一个最大值。
三、代码
我们在求最小值的时候需要注意初始化为正无穷的问题。
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
const int INF = 0x3f3f3f3f;
int a[N], f[N][N], g[N][N];
int n;
int main()
{cin >> n;for(int i = 1; i <= n; i ++ ){cin >> a[i];a[i + n] = a[i];}for(int i = 1; i <= 2 * n; i ++ ){a[i] = a[i - 1] + a[i];}for(int len = 2; len <= n; len ++ ){for(int l = 1; l + len - 1 <= 2 * n; l ++ ){int r = l + len -1;g[l][r] = INF;for(int k = l; k < r; k ++ ){f[l][r] = max(f[l][r], f[l][k] + f[k + 1][r] + a[r] - a[l - 1]);g[l][r] = min(g[l][r], g[l][k] + g[k + 1][r] + a[r] - a[l - 1]);}}}int maxv = -INF, minv = INF;for(int l = 1; l + n - 1 <= 2 * n; l ++ ){int r = l + n - 1;if(maxv < f[l][r])maxv = f[l][r];if(minv > g[l][r])minv = g[l][r];} cout << minv << endl << maxv << endl;}
AcWing 1068. 环形石子合并(环形区间DP)相关推荐
- 算法基础课-动态规划-区间dp-AcWing 282. 石子合并:区间dp
文章目录 题目分析 题目链接 题目分析 只能合并相邻两堆.求体力最小值 数据比较弱,最多300堆,每堆重量不超过1000. 状态表示 f[i][j]表示合并区间[i,j]需要的最小体力 状态转移 把区 ...
- SDNU 1048.石子合并2(区间dp)
Description 有n堆石子排成一圈,每次选择相邻的两堆石子,将其合并为一堆,记录该次合并的得分为两堆石子个数之和.已知每堆石子的石子个数,求当所有石子合并为一堆时,最小的总得分. Input ...
- 石子合并(区间dp)
题目链接 设有N堆石子排成一排,其编号为1,2,3,-,N. 每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆. 每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合 ...
- AcWing 1068. 环形石子合并
AcWing 1068. 环形石子合并 题意: n堆石头围成一个圈,然后将相邻两堆合并成新的一堆,得分为新的一堆的石头数 问最高得分合最低得分 题解: 很简单,区间dp的模板题 和这个题一样 状态转移 ...
- 区间DP之环形石子合并
环形石子合并 题目传送门 题目描述 将 n 堆石子绕圆形操场排放,现要将石子有序地合并成一堆. 规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分. 请编写一个程序,读入堆 ...
- 石子合并(动态规划DP)
时限: 1000ms 内存限制:10000K 总时限:3000ms 描述: 在一个圆形操场的四周摆放着n堆石子(n<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成 ...
- CSP认证201612-4 压缩编码[C++题解]:区间dp、huffman树、石子合并
题目分析 来源:acwing 分析: 本题难在想到是区间dp.想到区间dp之后,这就是石子合并的代码直接默写. 那么是如何建模的呢?我们把huffman编码(这里要求按照字典序大小编码,和huffma ...
- dp2:线性dp、区间dp、计数dp.
线性dp 动态规划时间复杂度分析,状态数目与状态转移次数相乘. 数字三角形 数字三角形 以集合的观点考虑dp问题. #include<iostream> #include<cst ...
- AcWing 320. 能量项链(环形区间DP)
AcWing 320. 能量项链(环形区间DP) 一. 问题: 二.分析: 三.代码 一. 问题: 二.分析: 在讲解这道题之前,大家需要对线性区间DP和环形区间DP有一定的了解,因此如果不会这两个知 ...
最新文章
- 手动创建Spring项目 Spring framework
- HTML的标签描述20
- Centos与Ubuntu
- [Python人工智能] 二十七.基于BiLSTM-CRF的医学命名实体识别研究(下)模型构建
- ipython版本_1. Python版本的选择与安装
- 双语阅读:坚持你的方向
- 如何攻克 Android 调试难题?| 技术头条
- 安徽工程大学专升本计算机科学与技术专业,2015年安徽工程大学机电学院的计算机科学与技术专业怎么样...
- snackbar_Android Snackbar示例教程
- Flutter进阶第9篇:检测网络连接,监听网络变化
- winform 图片压缩大小为原图的一半_图片压缩指定大小?!这款神奇的工具有必要了解一下...
- 【数据分享】历次人口普查数据(一普到七普)
- 绿色IT实施必要性 数字可不会撒谎
- xiuno开发文档_$ip-XiunoPHP 4.0 开发手册
- uniapp请求的封装
- 字节跳动测开面经(两面 + HR)
- 接了个变态需求:生成 Excel + PDF 导出,用 Java 怎么实现?
- P1413 坚果保龄球 AC于2018.7.30
- MATLAB图像处理--高斯低通滤波、高斯高通滤波(代码及示例)
- MATLAB分段函数没有横线,关于matlab分段函数如何绘图问题
热门文章
- datetimepicker用法总结-设置控件只能选择一个月之内的日期
- Windows10触控板防误触
- [附源码]java毕业设计小型银行贷款管理系统
- String对比大小
- 超大规模OpenStack商用浪潮,看“浪潮”!
- Ubuntu的Intel网卡驱动安装
- 为什么会出现梯度爆炸和梯度消失现象?怎么缓解这种现象的发生?
- 热门免费的:YesPlayMusic Mac(高颜值网易云音乐第三方播放器)
- 配置服务器代理【setupProxy】代理http-proxy-middleware
- Filter过滤器用法与说明