ACM - ICPC World Finals 2013 H Матрёшка
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf
题目翻译:
问题描述
俄罗斯套娃是一些从外到里大小递减的传统的俄罗斯木头玩偶组成的。当你打开一个俄罗斯套娃时,里面就会露出一个同样的俄罗斯套娃,再打开,就会再露出一个,不断重复。
俄罗斯的俄罗斯套娃博物馆最近收藏了一些外形相似的俄罗斯套娃集,只是里面嵌套的玩偶数量不相等。不幸的是,有一群过分热情的(和明显无人监督的)孩子们拆了他们,并放在一行上。有n个玩偶在一上,每个都有一个整数的大小,你需要重新组装套娃集,你既不知道套娃集的数量,也不知道某个套娃集内玩偶的数量,你只知道一个完好的套娃集内的玩偶大小是从1到某个数字m
在组装套娃集时,你必须遵守下列规则:
1.你只能将一个玩偶或者套娃集放入一个更大的玩偶中
2.你只能把相邻两个俄罗斯套娃组合在一起
3.已经被合并的玩偶是不能再重新拆出来的。
你的时间很宝贵,你只想尽快的组装好。唯一需要耗时的部分为打开一个玩偶并马上关上它。所以你要尽可能少的做这种操作。比如说:合并[1,2,6]与[4],你需要将大小为4和6的两个玩偶拆开。合并[1,2,5]与[3,4]代价为3。
求将n个玩偶重新拼成一些完好的俄罗斯套娃的最小代价。
输入格式
第一行一个数n,第二行包含n个数,依次表示每个玩偶的大小。
输出 格式
如果答案存在,输出一个数表示将n个玩偶重新拼成一些完好的俄罗斯套娃的最小代价。否则输出“Impossible”
样例输入
7
1 2 1 2 4 3 3
样例输出
Impossible
样例输入
7
1 2 3 2 4 1 3
样例输出
7
数据规模和约定
1<=n<=500 , 1<=玩偶大小<=500
题目大意:
有n个套娃排成一列,我们要将它们合并成若干个完整的套娃(即这个套娃的最大一层为m,它里面包含从1~n-1所有大小的套娃各一个),每次只能选择相邻两个合并,且已经合并的套娃不可以拆开(在与其它套娃合并时可以临时拆开),问完成合并至少需要将套娃拆开多少次(例如将(3, 2)与(1)合并需要拆开两次)
思路分析:
这是一道区间DP的题目,看到数据范围和时间限制,大概是一个\(O(n^3)\)左右的复杂度。我们先预处理出\(g(i,\,j)\),表示将序列上的第i个套娃到第j个套娃合并成一个套娃(不需要是完整的套娃)需要拆开的最小次数。显然当i~j中存在相同大小的套娃时,\(g(i,\,j)=\infty\)(他们不可能被合并成一个)
我们可以轻松写出转移方程\[g(i,\,j)=\max_{(i\le k<j)}{\left\{g(i,\,k)+g(k+1,\,j)+f(i,\,k,\,j)\right\}},\]其中这个\(f(i,\,k,\,j)\)表示将合并完的(1~k)和(k + 1~j)合并起来所需的最小代价。通过观察可以发现我们不需要把两边的所有套娃全都拆开,但是至少要将一边的套娃全部拆开,而另一边只要拆到剩下的那一组套娃正巧可以放到完全拆开的那一组的最小的那一个套娃里面就好了,这等价于将求出两组套娃中的分别的最小值的较大者,小于这个较大者的套娃全部不用拆开而剩余的(包括这个较大者都需要拆开)。至此我们已经得到了\(f(i,\,k,\,j)\)的计算方法,然后\(g(i,\,j)\)就已经搞定了
接下来我们定义\(p(k)\)表示将前k个合并成若干个(多少个?不需要知道)完整的套娃需要的最小拆开次数,然后得到转移方程\[p(k)=\min_{1\le i<k}{\{p(i)+g(i+1,\,k)\}},\]然后就解决了。
算法流程:
1.DP计算\(g(i,\,j)\),在计算过程中对i~j进行局部排序,之后枚举k,并同时分别维护1~k与k+1~j中的最小值,然后计算得到解
在这里我有一点要说明的,排序的时候我建议使用计数排序,有两个原因:首先,套娃大小的范围与n的范围是相同的,使用计数排序可以保证渐进复杂度为线性,而快排之类的就会退化成\(O(n\log n)\)。第二,更重要的是,计数排序更容易维护每一个值的名次(否则需要二分查找,又是一个log)。
2.DP计算\(p(k)\)
3.\(p(n)\)即为所求
参考代码:
//date 20140123
#include <cstdio>
#include <cstring> const int maxn = ;
const int INF = ; inline int getint()
{
int ans(); char w = getchar();
while(w < '' || w > '')w = getchar();
while('' <= w && w <= '')
{
ans = ans * + w - '';
w = getchar();
}
return ans;
} inline int max(int a, int b){return a > b ? a : b;}
inline int min(int a, int b){return a < b ? a : b;} int n;
int a[maxn];
int count[maxn], count2[maxn];
int sum[maxn];
int exist[maxn];
int g[maxn][maxn];
int f[maxn]; inline int check(int l, int r)
{
memset(exist, , sizeof exist);
for(int i = l; i <= r; ++i)if(exist[a[i]])return false;
else ++exist[a[i]];
for(int i = ; i <= r - l + ; ++i)if(!exist[i])return false;
return true;
} int main()
{
freopen("matryoshka.in", "r", stdin);
freopen("matryoshka.out", "w", stdout); n = getint();
for(int i = ; i <= n; ++i) a[i] = getint();
memset(g, 0x7F, sizeof g);
for(int i = n; i; --i)
{
g[i][i] = ;
for(int j = i + ; j <= n; ++j)
{
g[i][j] = INF;
int Max(), flag(), Min1(INF), Min2(INF), ans(INF), Min(INF);
memset(count2, , sizeof count2);
memset(count, , sizeof count); for(int w = i; w <= j; ++w)
if(count2[a[w]]){flag = ; break;}
else {++count2[a[w]]; ++count[a[w]]; Min2 = min(Min2, a[w]); Max = max(Max, a[w]);}
if(flag)continue;
sum[Min2 - ] = ; for(int w = Min2; w <= Max; ++w)sum[w] = sum[w - ] + count[w]; for(int k = i; k < j; ++k)
{
--count2[a[k]];
Min1 = min(Min1, a[k]);
if(Min2 == a[k])for(Min2; !count2[Min2]; ++Min2); ans = min(ans, g[i][k] + g[k + ][j] + (j - i + ) - sum[max(Min1, Min2) - ]);
}
g[i][j] = ans;
}
} f[] = ;
for(int i = ; i <= n; ++i)f[i] = INF;
if(a[] == )f[] = ;
for(int i = ; i <= n; ++i)
{
for(int j = ; j < i; ++j)
if(check(j + , i)){f[i] = min(f[i], f[j] + g[j + ][i]);}
} if(f[n] != INF) printf("%d\n", f[n]);
else printf("Impossible\n");
return ;
}
需要注意的事项:
1.在计算\(g(i,\,j)\)时,如果需要赋值成无穷大,不要直接使用INT_MAX,因为我们会出现一个相加比较,这样一加就导致无穷大变成了负数
2.一定要注意递推的顺序
3.计算\(g(i,\,j)\)的时候不建议使用递归,因为我们需要维护一个当前i~j的顺序,需要另开数组,如果开在全局变量则需要开很多,如果开在局部变量则容易爆栈
ACM - ICPC World Finals 2013 H Матрёшка的更多相关文章
- ACM - ICPC World Finals 2013 C Surely You Congest
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 试题来源 ACM/ICPC World Fin ...
- ACM - ICPC World Finals 2013 A Self-Assembly
原题下载 : http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这道题其实是2013年我AC的第一道题,非常的开心,这 ...
- ACM - ICPC World Finals 2013 F Low Power
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 有n个机器,每个机器有2个芯片,每个 ...
- ACM - ICPC World Finals 2013 I Pirate Chest
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 海盗Dick受够了在公海上厮杀.抢劫 ...
- ACM - ICPC World Finals 2013 D Factors
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 一个最基本的算数法则就是大于1的整数 ...
- ACM - ICPC World Finals 2013 B Hey, Better Bettor
原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这题真心的麻烦……程序不长但是推导过程比较复杂,不太好想 ...
- [算法竞赛入门经典]Message Decoding,ACM/ICPC World Finals 1991,UVa213
Description Some message encoding schemes require that an encoded message be sent in two parts. The ...
- UVa210 Concurrency Simulator (ACM/ICPC World Finals 1991) 双端队列
Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but ...
- 谜题 (Puzzle,ACM/ICPC World Finals 1993,UVa227)
题目描述:算法竞赛入门经典习题3-5 题目思路:模拟题 #include <stdio.h> #include <string.h> #define maxn 55 char ...
随机推荐
- 管理员必须掌握的八个cmd命令
一.ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的:网络上的机器都有唯一确定的 ...
- SQL Server 2008 R2评估期已过的解决办法
SQL Server 2008 R2评估期已过的解决办法 发现问题 北美产品测试服每日随机任务没有刷新 每日随机任务是使用数据库作业定期执行操作,重置玩家随机任务项 排查问题 www.2cto. ...
- Codeforces Round #216 (Div. 2)解题报告
又范低级错误! 只做了两题!一道还被HACK了,囧! A:看了很久!应该是到语文题: 代码:#include<iostream> #include<]; ,m2=; ;i ...
- HDOJ 1398 Square Coins 母函数
Square Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 微信电脑版也能用公众号自定义菜单 微信1.2 for Windows发布
昨日,微信电脑版发布更新,版本为微信1.2 for Windows,最大的特色就是加入了保存聊天记录功能,可以使用公账号菜单,手机上收藏的表情也能在电脑版上发送,可以接收转账消息. 本次微信pc版更新 ...
- Sqli-labs less 19
Less-19 从源代码中我们可以看到我们获取到的是HTTP_REFERER 那和less18是基本一致的,我们从referer进行修改. 还是像less18一样,我们只给出一个示例 将referer ...
- 哪些问题困扰着我们?DevOps 使用建议
[编者按]随着 DevOps 被欲来越多机构采用,一些共性的问题也暴露出来.近日,Joe Yankel在「Devops Q&A: Frequently Asked Questions」一文中总 ...
- ZOJ题目分类
ZOJ题目分类初学者题: 1001 1037 1048 1049 1051 1067 1115 1151 1201 1205 1216 1240 1241 1242 1251 1292 1331 13 ...
- LINUX输入输出与文件——续
1 目录操作 改变目录或文件的访问权限 #include <sys/stat.h> int chmod(const char *path, mode_t mode); //mode形如07 ...
- Project Euler 104:Pandigital Fibonacci ends 两端为全数字的斐波那契数
Pandigital Fibonacci ends The Fibonacci sequence is defined by the recurrence relation: F[n] = F[n-1 ...