一个清晰的思路就是状压dp;不过也有AC自动机+BFS的做法

Description

给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串。

Input

第一行是一个正整数n(n<=12),表示给定的字符串的个数。
以下的n行,每行有一个全由大写字母组成的字符串。每个字符串的长度不超过50.

Output

只有一行,为找到的最短的字符串T。在保证最短的前提下,
如果有多个字符串都满足要求,那么必须输出按字典序排列的第一个。

Sample Input

2
ABCD
BCDABC

Sample Output

ABCDABC

题目分析

状压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]最短母串的更多相关文章

  1. bzoj 1195: [HNOI2006]最短母串 爆搜

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 894  Solved: 288[Submit][Status] ...

  2. BZOJ 1195: [HNOI2006]最短母串

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1346  Solved: 450[Submit][Status ...

  3. bzoj 1195 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机

    LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...

  4. 1195: [HNOI2006]最短母串 - BZOJ

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串.Input 第一行是一个正整数n(n<=12), ...

  5. BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)

    BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...

  6. bzoj 1195: [HNOI2006]最短母串【状压dp】

    我有病吧--明明直接枚举是否匹配就可以非要写hash,然后果然冲突了(--我个非酋居然还敢用hash 设f[s][i]为已选串状态为s并且最后一个串是i,还有预处理出g[i][j]表示最长有长为g[i ...

  7. 1195: [HNOI2006]最短母串

    思路:好像以前谁问过我这题...  状个压就好啦, 把包含在其他串中的字符串删掉, 预处理除每两个字符串之间的关系, dp[ state ][ i ] 表示在state的状态下, 最后一个字符串是第i ...

  8. 【刷题】BZOJ 1195 [HNOI2006]最短母串

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

  9. BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索

    思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...

随机推荐

  1. CODING 告诉你硅谷的研发项目管理之道(5)

    CODING 已经通过前四期文章,让大家逐步了解了一些硅谷优秀的项目管理者是如何工作.如何维持团队高效运作的.在过去的十几年中,中国的互联网行业发展过于迅猛,导致很多管理人员都是赶鸭子上架,商场如战场 ...

  2. [Java]ArrayList、LinkedList、Vector、Stack的比较

    一.介绍 先回顾一下List的框架图 由图中的继承关系,可以知道,ArrayList.LinkedList.Vector.Stack都是List的四个实现类. AbstractList是一个抽象类,它 ...

  3. php:两个文件夹递归地比较,没有的文件自动复制过去

    仿站时,通常默认模板文件和新的模板文件大部分都是一样的,下面代码可以用于比较文件是否缺失(和默认模板做比较) 如果缺失自动复制过去~~ <?php /** * used:新模板和default模 ...

  4. hadoop分布式存储(2)-hadoop的安装

    总共分三步:1.准备linux环境 租用“云主机”,阿里云,unitedStack等,云主机不受本机性能影响(或者直接安转linux操作系统或者虚拟机也行): PuTTy Configuration ...

  5. jetty jndi数据源

    applicationContext.xml <?xml version="1.0" encoding="utf-8"?> <beans de ...

  6. 062 Unique Paths 不同路径

    机器人位于一个 m x n 网格的左上角, 在下图中标记为“Start” (开始).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角,在下图中标记为“Finish”(结束).问有多少条不 ...

  7. tomcat7 fail to start inside Ubuntu Docker container

    The tomcat startup script needs some special privileges. Concrete it needs to check all running proc ...

  8. csrf攻击实例

    CSRF 攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在并未授权的情况下执行在权限保护之下的操作.比如说,受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求 ht ...

  9. 微服务实践分享(2)api网关

    1.作用[http://chuansong.me/n/465796751848]: 一个完整的.「面向接入」的API GW需要包含以下功能: 面向运行期 对客户端实现身份认证 通信会话的秘钥协商,报文 ...

  10. JavaWeb_05_xml相关&dtd快速入门

    学东西怎么学,是什么,能做什么,怎么去做!! 1.xml的简介 1.eXtensible Markup Language:可扩展标记型语言 标记型语言:html是标记型语言 也是使用标签来操作 可扩展 ...