*XXXIV. BZOJ3971 [WF2013]Матрёшка

摘自 DP 做题记录 II 例题 XXXIV.

仍然是神仙区间 DP。

直接设状态 \(f_{i,j}\) 表示区间 \([i,j]\) 的答案不太方便,考虑最终答案一定由若干段 \(1\sim m\) 的套娃合并在一起,所以我们设 \(f_{i,j}\) 表示把 \([i,j]\) 合并成一个套娃的最小代价并设 \(g_i\) 表示把长度 \(i\) 的前缀合并成若干个合法套娃的最小代价,则答案为 \(g_n\)。

考虑怎么算 \(f_{l,r}\):首先 \(l,r\) 不能有相同大小的套娃,记为 \(\mathrm{diff}(l,r)\)。然后枚举断点 \(k\),注意到 \([l,k]\) 所有大于 \(\min [k+1,r]\) 的套娃需要被拆开,以及 \([k+1,r]\) 所有大于 \(\min[l,k]\) 的套娃需要被拆开,这个可以二维前缀和预处理 \(s_{l,V}\) 表示 \(1\sim l\) 有多少个大小在 \(1\sim V\) 的套娃并 \(\mathcal{O}(1)\) 计算。记 \(\mathrm{merge}(l,k,r)\) 表示合并 \([l,k]\) 和 \([k+1,r]\) 的代价,则

\[f_{l,r}=\begin{cases}\min_{k=l}^{r-1}f_{l,k}+f_{k+1,r}+\mathrm{merge}(l,k,r)& \mathrm{diff}(l,r)\\\infty&\mathrm{otherwise}\end{cases}
\]

\(g\) 的转移是 trivial 的:

\[g_i=\min_{j=0}^{i-1}\begin{cases}g_j+f_{j+1,i} & \mathrm{mex}(j+1,i)=i-j+1\\\infty&\mathrm{otherwise}\end{cases}
\]

若 \(g_n=\infty\) 则输出 impossible,时间复杂度 \(\mathcal{O}(n^3)\)。

 const int N = 500 + 5;
const int inf = 1e8; int n, a[N], f[N], g[N][N], s[N][N], mi[N][N], mex[N][N], ck[N][N];
int cal(int l, int r, int x1, int x2) {
return s[r][x2] - s[l - 1][x2] - s[r][x1 - 1] + s[l - 1][x1 - 1];
}
void cmex(int l, int r) {
static int buc[N]; mem(buc, 0, N), mex[l][r] = 1;
for(int i = l; i <= r; i++) buc[a[i]] = 1;
while(buc[mex[l][r]]) mex[l][r]++;
}
void csam(int l, int r) {
static int buc[N]; mem(buc, 0, N);
for(int i = l; i <= r; i++)
ck[l][r] |= buc[a[i]], buc[a[i]] = 1;
}
int mer(int l, int k, int r) {
assert(l <= k && k < r && !ck[l][r]);
int m1 = mi[l][k], m2 = mi[k + 1][r];
return cal(l, k, m2, N - 1) + cal(k + 1, r, m1, N - 1);
}
int main() {
cin >> n, mem(mi, 31, N), mem(g, 31, N), mem(f, 31, N), f[0] = 0;
for(int i = 1; i <= n; i++) s[i][a[i] = read()]++, g[i][i] = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j < N; j++)
s[i][j] += s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1];
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
cmex(i, j), csam(i, j), mi[i][j] = min(mi[i][j - 1], a[j]);
for(int len = 2; len <= n; len++)
for(int l = 1, r = len; r <= n; l++, r++)
if(!ck[l][r]) for(int k = l; k < r; k++)
g[l][r] = min(g[l][r], g[l][k] + g[k + 1][r] + mer(l, k, r));
for(int i = 1; i <= n; i++)
for(int j = 0; j < i; j++)
if(mex[j + 1][i] == i - j + 1)
f[i] = min(f[i], f[j] + g[j + 1][i]);
if(f[n] >= inf) puts("Impossible");
else cout << f[n] << endl;
return 0;
}

BZOJ3971 [WF2013]Матрёшка的更多相关文章

  1. 【BZOJ】3971 [WF2013]Матрёшка

    [算法]区间DP [题解] 参考写法:BZOJ 3971 Матрёшка 解题报告 第二个DP可以预处理mex优化到O(nM+n2),不过我懒…… 第一个DP有另一种写法:不预处理,在一个n2取出来 ...

  2. ACM - ICPC World Finals 2013 H Матрёшка

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 俄罗斯套娃是一些从外到里大小递减的传 ...

  3. BZOJ 3971 Матрёшка 解题报告

    很自然想到区间 DP. 设 $Dp[i][j]$ 表示把区间 $[i, j]$ 内的套娃合并成一个所需要的代价,那么有: $Dp[i][i] = 0$ $Dp[i][j] = min\{Dp[i][k ...

  4. 区间dp提升复习

    区间\(dp\)提升复习 不得不说这波题真的不简单... 技巧总结: 1.有时候转移可以利用背包累和 2.如果遇到类似区间添加限制的题可以直接把限制扔在区间上,每次只考虑\([l,r]\)被\([i, ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. hibernate 中文文档

    转载:http://blog.csdn.net/kevon_sun/article/details/42850387 Hibernate Annotations 参考文档 3.2.0 CR1 目录 前 ...

  7. ACM International Collegiate Programming Contest World Finals 2013

    ACM International Collegiate Programming Contest World Finals 2013 A - Self-Assembly 题目描述:给出\(n\)个正方 ...

  8. BZOJ_3969_[WF2013]Low Power_二分答案

    BZOJ_3969_[WF2013]Low Power_二分答案 Description 有n个机器,每个机器有2个芯片,每个芯片可以放k个电池. 每个芯片能量是k个电池的能量的最小值. 两个芯片的能 ...

  9. bzoj 3969: [WF2013]Low Power 二分

    3969: [WF2013]Low Power Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...

随机推荐

  1. VMD可视化hdf5格式的分子坐标文件

    技术背景 VMD是分子动力学模拟领域常用的一款可视化软件,可以非常直观方便的展示分子的运动过程.而VMD本身对展现的格式有一定的要求,如果不是常见的rst等类型的坐标文件的话,就需要自己手动去实现一个 ...

  2. Docker制作能够ssh连接的镜像

    本类文章只作为记录使用 命令操作: #拉取Centos 7 docker pull centos:7 #运行一个镜像 docker run -tdi --privileged centos:7 ini ...

  3. JVM:垃圾收集器与对象的"存活"问题

    垃圾收集器垃圾收集(Garbage Collection,GC).当需要排查各种内存溢出.内存泄露问题时,当垃圾收集成为系统更高并发量的瓶颈时,我们需要去了解GC和内存分配. 检查对象的"存 ...

  4. threading python2 和python3

    from __future__ import division from __future__ import print_function import threading balance = 0 d ...

  5. hdu 1198 Farm Irrigation(并查集)

    题意: Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a ...

  6. shell 脚本控制命令的执行顺序

    &&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...

  7. 谷歌chrome多个相同用户登陆同一个机器多开配置

    创建快捷方式,目标中填写:路径+参数如下所示即可 参数:--user-data-dir=%LOCALAPPDATA%\Google\Chrome\%SessionName%

  8. Jenkins+SVN+Maven+testNG管理项目

    1.登录访问:http://localhost:8080/jenkins 2.系统管理 => 全局工具配置 => ADD JDK  AND  Add Maven 3.安装SVN插件:系统管 ...

  9. C++ pragma once 与 ifndef 用法区别

    #pragma once 与 #ifndef 的作用 (1)在C/C++中,在使用预编译指令#include的时候,为了防止重复引用造成二义性. (2)在能够支持这两种方式的编译器上,二者并没有太大的 ...

  10. 后台管理系统:vue&node&MongoDB(一)

    后台管理系统 使用工具: Vue    Node     Mongodb   Element-ui 一.后台(Node+Mongodb) 前期准备: 需要下载的包: mongooes -------- ...