一个清晰的思路就是状压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. STP-13-MST和其它STP版本的互操作性(没写完)

    为了理解MST和其他STP版本的互操作性,首先要来看看MST与没有每VLAN概念的纯IEEE802.1D STP或802.1w RSTP非MST交换机(本书称其为非MST交换机)之间互操作的方式.这些 ...

  2. Django框架之MVT(1)

    Django框架之MVT 灌输: 什么是根目录:就是没有路径,只有域名.  url(r”^$”) 一.     MVT模型 Django的MVT模型 -     Model(模板):和数据库相关,负责 ...

  3. 042 Trapping Rain Water 接雨水

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算下雨之后能接多少雨水.例如,输入 [0,1,0,2,1,0,1,3,2,1,2,1],返回 6. 详见:https://leetcode.c ...

  4. HDU 1260 Tickets DP

    http://acm.hdu.edu.cn/showproblem.php?pid=1260 用dp[i]表示处理到第i个的时候用时最短. 那么每一个新的i,有两个选择,第一个就是自己不和前面的组队, ...

  5. CallContext的LogicalCallContext在多线程环境下面公用变量

    压根名听说过这个类的看这里:如何实现对上下文(Context)数据的统一管理 原来以为CallContext就可以直接在多线程环境下面共享使用的,今天突然想到:Asp.Net环境下面,设置来设置去的, ...

  6. TCP/IP协议分析含义与功能

    TCP/IP协议模型从更实用的角度出发,形成了高效的四层体系结构,即网络接口层.IP层.传输层和应用层.TCP/IP是一组专业化协议,包括IP.TCP.UDP.ARP.ICMP以及其它的一些被称为子协 ...

  7. SpringBoot服务监控

    SpringBoot服务监控分为客户端和服务端,即服务端是监控方,客户端为被监控方. 例如需要对线上的SpringBoot服务project-A进行监控,则project-A 为客户端.而监控的服务p ...

  8. checkbox 全选 单选的使用

    绑定数据 if (!IsPostBack) { using (UsersDataContext con = new UsersDataContext()) { Repeater1.DataSource ...

  9. SQL server的一个分割表值函数

    CREATE FUNCTION [dbo].[Fn_Split] ( @SplitString text, -- 如果要传入NText类型,下面需要相应的修改,注释行为NText下同 ) = ','- ...

  10. android测试开发环境搭建

    本文档针对未接触过android的0基础人员,在开始熟悉android之前,首先需要一个学习环境来支撑,在此简单介绍一下android环境搭建.(当然大家也可以百度.谷歌,类似的文档很多) 环境搭建: ...