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 ...
随机推荐
- C#顺序表(数据结构)
xmfdsh我近来心情实在不好,只因为这两天课比较少,然后一下子时间太多,不知道干什么,心情郁闷......这是要闹哪样?这都让我一个郁闷了一个晚上.闲来无聊,回顾下之前学的C#数据结构,数据结构的重 ...
- [翻译]Kafka Streams简介: 让流处理变得更简单
Introducing Kafka Streams: Stream Processing Made Simple 这是Jay Kreps在三月写的一篇文章,用来介绍Kafka Streams.当时Ka ...
- JavaScript 中的 this
JavaScript 语言中的 this 由于其运行期绑定的特性,JavaScript 中的 this 含义要丰富得多,它可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式.JavaSc ...
- 国内银行CNAPS CODE 查询
原地址:http://weekend.blog.163.com/blog/static/746895820127961346724/ 全国各地,无论哪个银行,无论什么分行,所有的CNAPS CODE都 ...
- HYSBZ2038 小Z的袜子(莫队算法)
今天学了一下传说中的解决离线询问不修改的一种算法.题目的意思非常简单,就是询问在一个[L,R]区间里的取两个物品,然后这两个物品颜色相同的概率.其实就是对于每种颜色i,这个区间里对应的个数cnt[i] ...
- POJ 2010
Moo University - Financial Aid Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 4235 A ...
- BroadcastReceiver应用1
有两种注册方式:1. 在AndroidManifest中注册.2. 在代码中直接注册,这种注册需要注意的一点是:当注册此Receiver的Activity退出的时候,一定要调用unregisterRe ...
- node-debug 三法三例之node debugger + node inspector
大家对nodejs调试应该都比较头疼,至少我这个不用IDE写js的人很头疼这个,其实node的生态圈非常好 有非常好的工具和非常潮的开发方式 这里总结了3法3例,希望能对大家有所帮助 文档地址 ht ...
- springmvc的系统学习之配置方式
资源:尚学堂 邹波 springmvc框架视频 一.springMVC 工作流程 页面请求---->控制器(Controller DispatcherServlet)----& ...
- sin=in.readLine();
import java.io.*; public class LineIO{ public static void main(String[] args) { String sin,inputStri ...