题目

第一类区间DP模板题。

所谓第一类区间DP,是指合并型区间DP,状态转移方程一般形如 \(f_{i,j}=\max{f_{i,k}+f_{k+1,j}+cost_{i,j}}\) ,时间复杂度一般是 \(O(n^3)\)。

这道题因为在环上,不能直接套板子,我们考虑:

  1. 断环成链,时间复杂度 \(O(n^4)\) 。如果加火车头之类的东西的话勉强能卡过去。
  2. 倍长原环,做完DP以后在长度为 \(n\) 的 \(n\) 个区间内找最优解。时间复杂度 \(O(n^3)\),可以通过本题。

就本题而言,状态转移方程可以套用板子。\(f_{i,j}=\max{f_{i,k}+f_{k+1,j}+\begin{matrix} \sum_{m=i}^j a[m] \end{matrix}}\)。

代码:

  1. #include<stdio.h>
  2. #define reg register
  3. #define ri reg int
  4. #define rep(i, x, y) for(ri i = x; i <= y; ++i)
  5. #define nrep(i, x, y) for(ri i = x; i >= y; --i)
  6. #define DEBUG 1
  7. #define ll long long
  8. #define il inline
  9. #define swap(a, b) ((a) ^= (b) ^= (a) ^= (b))
  10. #define max(i, j) (i) > (j) ? (i) : (j)
  11. #define min(i, j) (i) < (j) ? (i) : (j)
  12. #define read(i) io.READ(i)
  13. #define print(i) io.WRITE(i)
  14. #define push(i) io.PUSH(i)
  15. struct IO {
  16. #define MAXSIZE (1 << 20)
  17. #define isdigit(x) (x >= '0' && x <= '9')
  18. char buf[MAXSIZE], *p1, *p2;
  19. char pbuf[MAXSIZE], *pp;
  20. #if DEBUG
  21. #else
  22. IO() : p1(buf), p2(buf), pp(pbuf) {}
  23. ~IO() {
  24. fwrite(pbuf, 1, pp - pbuf, stdout);
  25. }
  26. #endif
  27. inline char gc() {
  28. #if DEBUG
  29. return getchar();
  30. #endif
  31. if(p1 == p2)
  32. p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
  33. return p1 == p2 ? ' ' : *p1++;
  34. }
  35. inline bool blank(char ch) {
  36. return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
  37. }
  38. template <class T>
  39. inline void READ(T &x) {
  40. register double tmp = 1;
  41. register bool sign = 0;
  42. x = 0;
  43. register char ch = gc();
  44. for(; !isdigit(ch); ch = gc())
  45. if(ch == '-') sign = 1;
  46. for(; isdigit(ch); ch = gc())
  47. x = x * 10 + (ch - '0');
  48. if(ch == '.')
  49. for(ch = gc(); isdigit(ch); ch = gc())
  50. tmp /= 10.0, x += tmp * (ch - '0');
  51. if(sign) x = -x;
  52. }
  53. inline void READ(char *s) {
  54. register char ch = gc();
  55. for(; blank(ch); ch = gc());
  56. for(; !blank(ch); ch = gc())
  57. *s++ = ch;
  58. *s = 0;
  59. }
  60. inline void READ(char &c) {
  61. for(c = gc(); blank(c); c = gc());
  62. }
  63. inline void PUSH(const char &c) {
  64. #if DEBUG
  65. putchar(c);
  66. #else
  67. if(pp - pbuf == MAXSIZE) {
  68. fwrite(pbuf, 1, MAXSIZE, stdout);
  69. pp = pbuf;
  70. }
  71. *pp++ = c;
  72. #endif
  73. }
  74. template <class T>
  75. inline void WRITE(T x) {
  76. if(x < 0) {
  77. x = -x;
  78. PUSH('-');
  79. }
  80. static T sta[35];
  81. T top = 0;
  82. do {
  83. sta[top++] = x % 10;
  84. x /= 10;
  85. } while(x);
  86. while(top)
  87. PUSH(sta[--top] + '0');
  88. }
  89. template <class T>
  90. inline void WRITE(T x, char lastChar) {
  91. WRITE(x);
  92. PUSH(lastChar);
  93. }
  94. } io;
  95. int n, a[210], sum[210];
  96. int f1[210][210], f2[210][210];
  97. int main() {
  98. ll ans = 1ll << 50;
  99. read(n);
  100. rep(i, 1, n) read(a[i]), a[i + n] = a[i];
  101. rep(i, 1, n + n) sum[i] = sum[i - 1] + a[i];
  102. rep(i, 1, 2 * n) rep(j, 1, 2 * n) {
  103. if(i == j) f1[i][j] = 0;
  104. else f1[i][j] = 1 << 29;
  105. f2[i][j] = 0;
  106. }
  107. rep(len, 1, n) {
  108. rep(i, 1, n * 2 - len - 1) {
  109. ri j = i + len - 1;
  110. rep(k, i, j - 1) {
  111. f1[i][j] = min(f1[i][j], f1[i][k] + f1[k + 1][j] + sum[j] - sum[i - 1]);
  112. f2[i][j] = max(f2[i][j], f2[i][k] + f2[k + 1][j] + sum[j] - sum[i - 1]);
  113. }
  114. }
  115. }
  116. rep(i, 1, n) ans = min(ans, f1[i][i + n - 1]);
  117. print(ans);
  118. puts("");
  119. ans = 0;
  120. rep(i, 1, n) ans = max(ans, f2[i][i + n - 1]);
  121. print(ans);
  122. }

注意初始化都要开到 \(2\times n\)

洛谷P1880题解的更多相关文章

  1. 石子合并2——区间DP【洛谷P1880题解】

    [区间dp让人头痛……还是要多写些题目练手,抽空写篇博客总结一下] 这题区间dp入门题,理解区间dp或者练手都很妙 ——题目链接—— (或者直接看下面) 题面 在一个圆形操场的四周摆放N堆石子,现要将 ...

  2. [codevs1048]石子归并&[codevs2102][洛谷P1880]石子归并加强版

    codevs1048: 题目大意:有n堆石子排成一列,每次可合并相邻两堆,代价为两堆的重量之和,求把他们合并成一堆的最小代价. 解题思路:经典区间dp.设$f[i][j]$表示合并i~j的石子需要的最 ...

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

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

  4. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  5. 洛谷P5759题解

    本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...

  6. 关于三目运算符与if语句的效率与洛谷P2704题解

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

  7. 洛谷P1880 石子合并(区间DP)(环形DP)

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

  8. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  9. 洛谷P2607题解

    想要深入学习树形DP,请点击我的博客. 本题的DP模型同 P1352 没有上司的舞会.本题的难点在于如何把基环树DP转化为普通的树上DP. 考虑断边和换根.先找到其中的一个环,在上面随意取两个点, 断 ...

随机推荐

  1. 『动善时』JMeter基础 — 50、使用JMeter测试WebService接口

    目录 1.什么是WebService 2.WebService和SOAP的关系 3.什么是WSDL 4.测试WebService接口前的准备 (1)如何判断是WebService接口 (2)如何获取W ...

  2. Arduino库和STM32的寄存器、标准库、HAL库、LL库开发比较之GPIO

    标题: Arduino库和STM32的寄存器.标准库.HAL库.LL库开发比较之GPIO 作者: 梦幻之心星 sky-seeker@qq.com 标签: [#Arduino,#STM32,#库,#开发 ...

  3. MySQL数据库快速入门与应用实战(阶段一)

    MySQL数据库快速入门与应用实战(阶段一) 作者 刘畅 时间 2020-09-02 实验环境说明: 系统:centos7.5 主机名 ip 配置 slavenode3 172.16.1.123 4核 ...

  4. layui--入门(helloWorld)

    具体可参考官方文档:https://www.layui.com/doc/ 由于引入layui 需要用到node.js 安装过程可参考: https://www.cnblogs.com/liuchenx ...

  5. kotlin gradle 生成jni头文件

    目录 问题 解决方法 使用方法 代码 gradle task位置截图 问题 最近在用kotlin写jni,但是生成头文件的时候遇到了些问题. 首先 javah 在java >= 1.9 就被取消 ...

  6. XCTF logmein

    一.查壳 发现是64位的Linux文件(ELF可以看出是linux的文件) 二.拖入ida64,静态分析 注意这里两个坑: 1.strcpy是复制字符串的意思,前面定义的v8数组只有8个,但是后面的字 ...

  7. Java核心基础第4篇-Java数组的常规操作

    Java数组 一.数组简介 数组是多个相同类型数据的组合,实现对这些数据的统一管理 数组属引用类型,数组型数据是对象(Object) 数组中的元素可以是任何数据类型,包括基本类型和引用类型 数组类型是 ...

  8. 虚拟机centos7环境搭建,系统分区,静态IP配置

    文章目录 1.虚拟机安装centos7 2.系统分区 3.配置静态IP centos7下载地址 http://mirrors.aliyun.com/centos/7/isos/x86_64/ Cent ...

  9. go logrus实战应用

    简单记录一下logrus实战应用,详细了解可以移步官网,这是直接使用 上代码: logrus整个项目应用封装 package log import ( "fmt" "gi ...

  10. Anaconda软件安装使用问题

    目录 更新源 用conda安装包出现的环境不一致问题 更新源 命令行 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/ ...