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)相关推荐

  1. 算法基础课-动态规划-区间dp-AcWing 282. 石子合并:区间dp

    文章目录 题目分析 题目链接 题目分析 只能合并相邻两堆.求体力最小值 数据比较弱,最多300堆,每堆重量不超过1000. 状态表示 f[i][j]表示合并区间[i,j]需要的最小体力 状态转移 把区 ...

  2. SDNU 1048.石子合并2(区间dp)

    Description 有n堆石子排成一圈,每次选择相邻的两堆石子,将其合并为一堆,记录该次合并的得分为两堆石子个数之和.已知每堆石子的石子个数,求当所有石子合并为一堆时,最小的总得分. Input ...

  3. 石子合并(区间dp)

    题目链接 设有N堆石子排成一排,其编号为1,2,3,-,N. 每堆石子有一定的质量,可以用一个整数来描述,现在要将这N堆石子合并成为一堆. 每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合 ...

  4. AcWing 1068. 环形石子合并

    AcWing 1068. 环形石子合并 题意: n堆石头围成一个圈,然后将相邻两堆合并成新的一堆,得分为新的一堆的石头数 问最高得分合最低得分 题解: 很简单,区间dp的模板题 和这个题一样 状态转移 ...

  5. 区间DP之环形石子合并

    环形石子合并 题目传送门 题目描述 将 n 堆石子绕圆形操场排放,现要将石子有序地合并成一堆. 规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分. 请编写一个程序,读入堆 ...

  6. 石子合并(动态规划DP)

    时限: 1000ms 内存限制:10000K  总时限:3000ms 描述: 在一个圆形操场的四周摆放着n堆石子(n<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成 ...

  7. CSP认证201612-4 压缩编码[C++题解]:区间dp、huffman树、石子合并

    题目分析 来源:acwing 分析: 本题难在想到是区间dp.想到区间dp之后,这就是石子合并的代码直接默写. 那么是如何建模的呢?我们把huffman编码(这里要求按照字典序大小编码,和huffma ...

  8. dp2:线性dp、区间dp、计数dp.

    线性dp   动态规划时间复杂度分析,状态数目与状态转移次数相乘. 数字三角形 数字三角形 以集合的观点考虑dp问题. #include<iostream> #include<cst ...

  9. AcWing 320. 能量项链(环形区间DP)

    AcWing 320. 能量项链(环形区间DP) 一. 问题: 二.分析: 三.代码 一. 问题: 二.分析: 在讲解这道题之前,大家需要对线性区间DP和环形区间DP有一定的了解,因此如果不会这两个知 ...

最新文章

  1. 手动创建Spring项目 Spring framework
  2. HTML的标签描述20
  3. Centos与Ubuntu
  4. [Python人工智能] 二十七.基于BiLSTM-CRF的医学命名实体识别研究(下)模型构建
  5. ipython版本_1. Python版本的选择与安装
  6. 双语阅读:坚持你的方向
  7. 如何攻克 Android 调试难题?| 技术头条
  8. 安徽工程大学专升本计算机科学与技术专业,2015年安徽工程大学机电学院的计算机科学与技术专业怎么样...
  9. snackbar_Android Snackbar示例教程
  10. Flutter进阶第9篇:检测网络连接,监听网络变化
  11. winform 图片压缩大小为原图的一半_图片压缩指定大小?!这款神奇的工具有必要了解一下...
  12. 【数据分享】历次人口普查数据(一普到七普)
  13. 绿色IT实施必要性 数字可不会撒谎
  14. xiuno开发文档_$ip-XiunoPHP 4.0 开发手册
  15. uniapp请求的封装
  16. 字节跳动测开面经(两面 + HR)
  17. 接了个变态需求:生成 Excel + PDF 导出,用 Java 怎么实现?
  18. P1413 坚果保龄球 AC于2018.7.30
  19. MATLAB图像处理--高斯低通滤波、高斯高通滤波(代码及示例)
  20. MATLAB分段函数没有横线,关于matlab分段函数如何绘图问题

热门文章

  1. datetimepicker用法总结-设置控件只能选择一个月之内的日期
  2. Windows10触控板防误触
  3. [附源码]java毕业设计小型银行贷款管理系统
  4. String对比大小
  5. 超大规模OpenStack商用浪潮,看“浪潮”!
  6. Ubuntu的Intel网卡驱动安装
  7. 为什么会出现梯度爆炸和梯度消失现象?怎么缓解这种现象的发生?
  8. 热门免费的:YesPlayMusic Mac(高颜值网易云音乐第三方播放器)
  9. 配置服务器代理【setupProxy】代理http-proxy-middleware
  10. Filter过滤器用法与说明