【状态压缩dp】1195: [HNOI2006]最短母串
一个清晰的思路就是状压dp;不过也有AC自动机+BFS的做法
Description
给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串。
Input
Output
Sample Input
ABCD
BCDABC
Sample Output
题目分析
状压dp
看到数据范围,自然想到状压dp。$f[t][i]$表示“已经选了$t$这个状态,第$i$个是最后一个选的”状态下最短长度。那么转移时候就是常规的状压dp转移。
至于处理两个字符串最长公共前后缀长度,我是用hash去做的。当然在AC自动机上根据fail边跳也不失为一种好方法。
#include<bits/stdc++.h>
typedef unsigned int uint;
const int maxn = ;
const int base = ; std::string str[][maxn],s[maxn],sv[maxn],tmp;
int n,all,cnt,mn;
uint power[maxn];
int lens[maxn],num[maxn][maxn],f[][maxn]; int main()
{
memset(f, 0x3f3f3f3f, sizeof f);
scanf("%d",&n);
all = (<<n)-, power[] = ;
for (int i=; i<=n; i++)
std::cin >> s[i], lens[i] = s[i].length();
for (int i=1; i<=53; i++) power[i] = power[i-1]*base; //之前把这个循环放在1..n的循环里了…… 以后预处理还是要小心数据范围。
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (i^j){
int l = std::min(lens[i], lens[j]);
uint val1 = , val2 = ;
for (int t=; t<l; t++)
{
val1 = val1+power[t]*(s[i][lens[i]-t-]-'A'+);
val2 = val2*base+s[j][t]-'A'+;
if (val1==val2) num[i][j] = t+;
}
}
mn = f[][], f[][] = ;
for (int j=, tst=; j<=n; j++, tst=<<(j-))
f[tst][j] = lens[j], str[tst][j] = s[j];
for (int p=; p<all; p++)
for (int i=, sst=; i<=n; i++, sst=<<(i-))
if (p&sst)
for (int j=, tst=; j<=n; j++, tst=<<(j-))
if (!(p&tst)){
tmp = str[p][i]+s[j].substr(num[i][j], lens[j]-num[i][j]);
if (f[p+tst][j] > f[p][i]+lens[j]-num[i][j]){
f[p+tst][j] = f[p][i]+lens[j]-num[i][j];
str[p+tst][j] = tmp;
}else if (f[p+tst][j]==f[p][i]+lens[j]-num[i][j]&&tmp < str[p+tst][j])
str[p+tst][j] = tmp; //j和tst一开始没有分清
}
for (int i=; i<=n; i++)
if (f[all][i] < mn){
mn = f[all][i], cnt = ;
sv[cnt] = str[all][i];
}else if (f[all][i]==mn) sv[++cnt] = str[all][i];
std::sort(sv+, sv+cnt+);
std::cout << sv[];
return ;
}
AC自动机+BFS
老早就听说过这个思路,不过写完状压dp去看题解时候才好好想了想。
这个做法相对来说要抽象一些。不过也算是AC自动机的一种套路应用吧。
这里按顺序枚举保证了字典序最小;BFS保证了长度最小。
Bzoj1195 [HNOI2006]最短母串 [AC自动机]
END
【状态压缩dp】1195: [HNOI2006]最短母串的更多相关文章
- bzoj 1195: [HNOI2006]最短母串 爆搜
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 894 Solved: 288[Submit][Status] ...
- BZOJ 1195: [HNOI2006]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1346 Solved: 450[Submit][Status ...
- bzoj 1195 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机
LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...
- 1195: [HNOI2006]最短母串 - BZOJ
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串.Input 第一行是一个正整数n(n<=12), ...
- BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)
BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...
- bzoj 1195: [HNOI2006]最短母串【状压dp】
我有病吧--明明直接枚举是否匹配就可以非要写hash,然后果然冲突了(--我个非酋居然还敢用hash 设f[s][i]为已选串状态为s并且最后一个串是i,还有预处理出g[i][j]表示最长有长为g[i ...
- 1195: [HNOI2006]最短母串
思路:好像以前谁问过我这题... 状个压就好啦, 把包含在其他串中的字符串删掉, 预处理除每两个字符串之间的关系, dp[ state ][ i ] 表示在state的状态下, 最后一个字符串是第i ...
- 【刷题】BZOJ 1195 [HNOI2006]最短母串
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...
- BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索
思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...
随机推荐
- jar包冲突问题
这两天在启动一个新项目的时候,项目一直启动不了,报StackOverFlow; java.util.concurrent.ExecutionException: java.lang.StackOver ...
- python——基本数据类型1——简介
列表 列表是可变数据类型.是序列类型; 列表的内容可以是数字,字符串和其它列表: 0第一个元素,-1最后一个元素, 定义连续列表 li = list(range(1,10,2)) 列表取值: 取 b: ...
- 牛客网Java刷题知识点之抽象类与接口
不多说,直接上干货! 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于它们的存在才赋予java强大的面向对象的能力. ...
- untiy3d开发环境搭建和开发准备
1.到untiy3d官网上下载untiy3d的软件(这里我使用的是个人版的5.3.61f做学习使用) 2.安装vs2012 3.因为unity3d和vs的版本有一定的版本对应关系,我这里使用vs201 ...
- Css+Html
CSS样式 <style type="text/css"> tt.tt1 { <style type="text/css"> p { b ...
- SpringBoot 2.x (15):Actuator监控
Actuator监控:SpringBoot自带的,对生成环境进行监控的系统 使用:既然是监控,那就不能监控一个空项目 这里我使用SpringBoot整合MyBatis的Demo: https://ww ...
- ABAP接口用法
1.定义接口INTERFACE intf [PUBLIC]. [components] ENDINTERFACE. 2.注意点: 2.1.接口中所定义的所有东西默认都是公共的,所以不用也不能写PU ...
- Android 使用RecyclerView实现多行水平分页的GridView效果和ViewPager效果
前些天看到有人在论坛上问这种效果怎么实现,没写过也没用过这个功能,网上查了一下,大多是使用ViewPager+GridView或者HorizontalScrollView+GridView实现,不过貌 ...
- Linux下使用crontab命令配置定时任务
一.语法结构 crontab [-e [UserName]|-l [UserName]|-r [UserName]|-v [UserName]|File ] 说明 : crontab 是用来让使用者在 ...
- TCP连接建立与关闭
http://hi.baidu.com/psorqkxcsfbbghd/item/70f3bd91943b9248f14215cd TCP连接建立与关闭 TCP 是一个面向连接的协议,无论哪一方向另一 ...