一道区间dp的模板题,这里主要记一下dp时环形数据的处理

简略版:方法一:枚举分开的位置,将圈化为链,因此要做n次。

    方法二:将链重复两次,即做一个2n-1长度的链,其中第i(i<=n)堆石子与i+n堆相同。

        对整个长链dp后,枚举(1, n), (2, n+1) ... (n, 2n-1),取最值即可。

题目描述

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

由于只有相邻的石子才能被合成为一堆,因此在所有时刻的任意一堆石子(无论被合成了几次)都可以看做相邻几堆石子的和。即,均可以用一个闭区间[l, r]表示。
进行动态规划时,两堆石子的合并可以被看作两个区间的合并,即两个小区间的信息向一个大区间转移
为处理环形数据,这里采用的方法是将数组arr重复两次,即arr[i+n] = arr[i](i<=n)。
设sum[i]为数组arr(重复后)的前缀和,dp1[i][j]、dp2[i][j]分别为第i堆至第j堆石子合并的得分最小值、最大值。
状态转移方程:

dp1[i][j] = min{dp1[i][k] + dp1[k+][j] + sum[j] - sum[i-]}
dp2[i][j] = max{dp2[i][k] + dp2[k+][j] + sum[j] - sum[i-]}
(i <= k <= j-)

注意初始化dp1[i][i] = INF,dp2[i][i] = 0。

代码实现后时间复杂度为O(8n3),相对与朴素的拆环方式(枚举断点做n次dp)的时间复杂度O(n4)在数据较大时有优势。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MAXN 300
using namespace std;
int dp1[MAXN][MAXN], dp2[MAXN][MAXN];
int arr[MAXN], sum[MAXN];
int n, ans_min = INF, ans_max = -;
void in_put(){
scanf("%d", &n);
for(int i=; i<=n; i++){
scanf("%d", &arr[i]);
arr[i+n] = arr[i];
}
}
void dp(){
for(int len=; len<=n; len++){
for(int i=; i<=*n; i++){
int end = i + len - ;
dp1[i][end] = INF, dp2[i][end] = -;
for(int j=i; j<end; j++){
dp1[i][end] = min(dp1[i][end], dp1[i][j] + dp1[j+][end]);
dp2[i][end] = max(dp2[i][end], dp2[i][j] + dp2[j+][end]);
}
dp1[i][end] += sum[end] - sum[i-];
dp2[i][end] += sum[end] - sum[i-];
}
}
for(int i=; i<=n; i++){
if(dp1[i][i+n-] < ans_min) ans_min = dp1[i][i+n-];
if(dp2[i][i+n-] > ans_max) ans_max = dp2[i][i+n-];
}
}
int main(){
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
in_put();
for(int i=; i<=n*; i++){
sum[i] = sum[i-] + arr[i];
dp1[i][i] = , dp2[i][i] = ;
}
dp();
printf("%d\n%d", ans_min, ans_max);
return ;
}

NOI1995 石子合并 [Luogu P1880]的更多相关文章

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

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

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

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

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

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

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

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

  5. P1880 [NOI1995]石子合并 区间dp

    P1880 [NOI1995]石子合并 #include <bits/stdc++.h> using namespace std; ; const int inf = 0x3f3f3f3f ...

  6. [LUOGU] P1880 [NOI1995]石子合并

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

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

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

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

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

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

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

随机推荐

  1. 滴滴热力图-php版(后面有js版本)

    ) * ) ) * ) {) * *pi() / ) * ]) % ) {//在多边形外return false;} else { //在多边形内return true;} }

  2. kubernetes垃圾回收器GarbageCollector源码分析(一)

    kubernetes版本:1.13.2 背景 由于operator创建的redis集群,在kubernetes apiserver重启后,redis集群被异常删除(包括redis exporter s ...

  3. Windows系统调用中API从3环到0环(下)

     Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API从3环到0环(下) 如果对API在 ...

  4. springboot 快速开发的定制补充

    增强 SpringBoot 快速开发工具 项目地址:https://gitee.com/sanri/web-ui 优点:这是一个 web 通用配置的组件,即插即用,可用于新项目或私活.是对 Sprin ...

  5. 基于常规DNS隧道进行的tcp端口转发dns2tcp的使用

    0x01 安装Dns2TCP dns2tcp 是一个利用DNS隧道转发TCP连接的工具,使用C语言开发. sudo apt-get install dns2tcp 0x02配置dns2tcp 配置DN ...

  6. Linux提权中常见命令大全

    在拿到一个 webshell 之后,大家首先会想到去把自己的权限提升到最高,windows 我们会提升到 SYSTEM 权限,而 Linux 我们会提升到 root 权限,拿在进行 Linux 提权的 ...

  7. table表格中文字超出显示省略号

    第一步: table {table-layout:fixed:}列宽由表格宽度和列宽度设定,不随文字多少变化 第二步: td { white-space:nowrap;/*文本不会换行,文本会在在同一 ...

  8. opencv::自定义角点检测

    #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...

  9. linux自启动脚本.sh

    while [ 1 ]; do              PRO_NUM=`ps -ef | grep "cms$" | grep -v "grep" | wc ...

  10. openssl之aes对称加密

    AES:密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 Rijndael加密法. 对称加密:用同一个密码  加密/解密  文件. 使用openssl中 ...