BZOJ 3971 Матрёшка 解题报告
很自然想到区间 DP。
设 $Dp[i][j]$ 表示把区间 $[i, j]$ 内的套娃合并成一个所需要的代价,那么有:
- $Dp[i][i] = 0$
 - $Dp[i][j] = min\{Dp[i][k] + Dp[k + 1][j] + Merge([i, k], [k + 1, j])\} (i \le k < j)$
 
于是问题在于算 $Merge([a, b], [c, d])$。
我们考虑一下:区间 $[a, b]$ 内的哪些套娃是需要打开的:
是不是 $[a, b]$ 中所有大于 $[c, d]$ 中最小的套娃都需要打开,来装 $[c, d]$ 中最小的套娃呢?
$[c, d]$ 同理。
于是我们可以预处理 $Sum[i][x]$ 为在前 $i$ 个套娃中,大小 $\le x$ 的套娃的个数,
那么就可以 $O(1)$ 地算 $Merge([a, b], [c, d])$ 了。
有一个问题,如果在 $[a, b]$、$[c, d]$ 中有相同大小的套娃怎么办?
不着急,先往下看。
处理完 $Dp[i][j]$ 后,我们再设立一个 $F[i]$ 表示把前 $i$ 个套娃装成若干个完好的套娃集所需代价的最小值,那么就有:
- $F[i] = min(F[j] + Dp[j + 1][i]) (mex([j + 1, i]) = i - j + 1)$
 - $mex([u, v]) = min(x) (x\notin \{A_u, A_{u+1}, \dots, A_v\})$
 
当然,如果不能找到合法的转移点,那么令 $F[i] = INF$。
然后对于一个合法的方案,不可能出现相同大小的套娃被装进同一个套娃内的情况,
所以 $[a, b]$、$[c, d]$ 中有相同大小的套娃的话,那么这个区间一定不合法,所以我们大可不必考虑那么多了。
于是最后看 $F[n]$ 就可以了。令 $M = max\{A_i\}$
时间复杂度 $O(n^3 + n^2M)$,空间复杂度 $O(n^2 + nM)$。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 500 + 5
#define INF 593119681 int n, Max;
int A[N], _Dp[N], T[N];
int Sum[N][N], Dp[N][N], Mex[N][N], Min[N][N]; inline void Prepare()
{
for (int i = ; i <= n; i ++)
Sum[i][A[i]] ++;
for (int i = ; i <= n; i ++)
for (int j = ; j <= Max; j ++)
Sum[i][j] += Sum[i][j - ] + Sum[i - ][j] - Sum[i - ][j - ]; for (int i = ; i <= n; i ++)
{
for (int j = ; j <= Max; T[j ++] = ) ;
for (int j = i; j <= n; j ++)
{
T[A[j]] ++;
for (Mex[i][j] = ; T[Mex[i][j]]; Mex[i][j] ++) ;
Min[i][j] = i == j ? A[i] : min(Min[i][j - ], A[j]);
}
}
} inline int Calc(int l, int mid, int r)
{
int min_1 = Min[l][mid], res = Sum[r][Max] - Sum[mid][Max] - Sum[r][min_1] + Sum[mid][min_1];
min_1 = Min[mid + ][r], res += Sum[mid][Max] - Sum[l - ][Max] - Sum[mid][min_1] + Sum[l - ][min_1];
return res;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("3971.in", "r", stdin);
freopen("3971.out", "w", stdout);
#endif scanf("%d", &n);
for (int i = ; i <= n; i ++)
{
scanf("%d", A + i);
Max = max(Max, A[i]);
}
Prepare();
for (int len = ; len < n; len ++)
for (int s = ; s + len <= n; s ++)
{
int i = s, j = s + len;
if (i == j) Dp[i][j] = ;
else
{
Dp[i][j] = INF;
for (int k = i; k < j; k ++)
Dp[i][j] = min(Dp[i][j], Dp[i][k] + Dp[k + ][j] + Calc(i, k, j));
}
}
for (int i = ; i <= n; i ++) _Dp[i] = INF;
for (int i = ; i <= n; i ++)
for (int j = ; j < i; j ++)
if (Mex[j + ][i] == i - j + )
_Dp[i] = min(_Dp[i], _Dp[j] + Dp[j + ][i]);
if (_Dp[n] >= INF) puts("Impossible");
else printf("%d\n", _Dp[n]); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}
3971_Gromah
BZOJ 3971 Матрёшка 解题报告的更多相关文章
- BZOJ 4619 Swap Space 解题报告
		
今天是因为David Lee正好讲这个题的类似题,我才做了一下. 本题是world final 2016的一道水…… 题目地址如下 http://www.lydsy.com/JudgeOnline/p ...
 - BZOJ 2839: 集合计数 解题报告
		
BZOJ 2839: 集合计数 Description 一个有\(N\)个元素的集合有\(2^N\)个不同子集(包含空集),现在要在这\(2^N\)个集合中取出若干集合(至少一个),使得 它们的交集的 ...
 - BZOJ 1367 [Baltic2004]sequence 解题报告
		
BZOJ 1367 [Baltic2004]sequence Description 给定一个序列\(t_1,t_2,\dots,t_N\),求一个递增序列\(z_1<z_2<\dots& ...
 - BZOJ 1044 木棍分割 解题报告(二分+DP)
		
来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limi ...
 - BZOJ 4341 [CF253 Printer] 解题报告
		
乍一看这个题好像可以二分优先度搞搞... 实际上能不能这么搞呢...? 我反正不会... 于是开始讲我的乱搞算法: 首先肯定要把任务按照优先度排序. 用一棵在线建点的线段树维护一个时刻是否在工作. 然 ...
 - BZOJ 4036 [HAOI2015] Set 解题报告
		
首先我们不能一位一位的考虑,为什么呢? 你想想,你如果一位一位地考虑的话,那么最后就只有 $n$ 个数字,然而他给了你 $2^n$ 个数字,怎么看都不对劲呀.(我是因为这样子弄没过样例才明白的) 所以 ...
 - BZOJ 3288 Mato矩阵 解题报告
		
这个题好神呀..Orz taorunz 有一个结论,这个结论感觉很优美: $$ans = \prod_{i=1}^{n}\varphi(i)$$ 至于为什么呢,大概是这样子的: 对于每个数字 $x$, ...
 - BZOJ 4123 [Baltic2015] Hacker 解题报告
		
首先,Alice 会选择一个长度为 $\lfloor\frac{n+1}{2}\rfloor$ 的区间,我们把这个长度记为 $len$. 有这么一个结论:令 $F_i$ 为覆盖 $i$ 点的所有长度为 ...
 - BZOJ 4146  [AMPPZ2014] Divisors 解题报告
		
这个题感觉比较小清新... 我们记录每个数出现的次数 $T_i$. 首先依次枚举每个数字,令 $ans = ans + T_i \times (T_i - 1)$,然后枚举这个数的倍数,令 $ans ...
 
随机推荐
- [转]让你提升命令行效率的 Bash 快捷键
			
生活在 Bash shell 中,熟记以下快捷键,将极大的提高你的命令行操作效率. 编辑命令 Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + f :按字符前移(右向) ...
 - SpringMVC框架
			
一.SpringMVC工作流程图 DispatcherServlet:Spring提供的前端控制器,所有的请求都有经过它来统一分发.在DispatcherServlet将请求分发给Spring Con ...
 - Redis主备复制
			
Redis 支持 Master-Slave(主从)模式,Redis Server 可以设置为另一个 Redis Server 的主机(从机),从机定期从主机拿数据.特殊的,一个从机同样可以设置为一个 ...
 - 将Word、Excel内容显示在Winform界面
			
这里使用到dsoframer.ocx插件 1. 首先下载dsoframer.ocx插件,下载地址: http://pan.baidu.com/s/1kTKHeIj 2. 注册该插件 Win7的做法是按 ...
 - 【高级JEE技术】JMS
			
ActiveMQ消息服务器. ActiveMQ是apache的一种jms标准实现,支持两种模型,点对点发送消息以及发布订阅者模型. 为了规范JMS API,JMS为消息传送定义了很多概念: JMS客户 ...
 - 我踩过的Alwayson的坑!(上集)
			
最近被sql server Alwayson高可用组和读写分离,弄得神魂颠倒,身心俱疲.遇到了下面一些问题,提醒自己也给后来人做些记录. EntityFramework支不支持Alwayson? 起因 ...
 - JQuery弹出层,实现弹层切换,可显示可隐藏。
			
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
 - css3 animation实现逐帧动画
			
css3里面的animation属性非常强大,但是自己用的比较少,最近有次面试就刚好被问到了,趁现在有时间就对animation做一个小总结.同时实现一个逐帧动画的demo作为练习 animation ...
 - 详解Windows 7系统中IE8/IE9/IE10三个版本的关系(转)
			
今年(2013)年初,微软开放了姗姗来迟的 IE10 for Windows 7 版本下载.至此,Windows 7 平台上可以运行三个 IE 浏览器版本.虽然 Windows 与 IE 经历了诸多版 ...
 - struts2的java文件中不能直接弹出script对话框
			
需要引入接口 ServletResponseAware public class Login extends ActionSupport implements SessionAware,Servlet ...