/*

难的不是ac自动机,是状态压缩dp

之前做了一两题类似题目,感觉理解的还不够透彻

*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int mxn=;
int L1[mxn*(<<)],L2[mxn*(<<)];
queue<int>q1,q2;
bool vis[mxn][(<<)];
int n;
int ans[mxn],num=;
struct ACa{
int t[mxn][];
int fail[mxn];
int end[mxn];
int S,cnt;
int q[],hd,tl;
void init(){S=cnt=;memset(end,,sizeof end);return;}
void insert(char *s,int id){
int len=strlen(s),now=S;
for(int i=;i<len;i++){
if(!t[now][s[i]-'A'])t[now][s[i]-'A']=++cnt;
now=t[now][s[i]-'A'];
}
end[now]|=(<<id);
}
void Build(){
hd=;tl=;
for(int i=;i<;i++)
if(t[S][i]){q[++tl]=t[S][i];fail[t[S][i]]=S;}
else t[S][i]=S;
while(hd<=tl){
int u=q[hd++];
int v,r;
for(int i=;i<;i++){
if(t[u][i]){
fail[t[u][i]]=t[fail[u]][i];
end[t[u][i]]|=end[t[fail[u]][i]];
q[++tl]=t[u][i];
}
else t[u][i]=t[fail[u]][i];
}
}
return;
}
void solve(){
hd=;tl=;int ed=(<<n)-;
q1.push(S),q2.push();
while(hd<=tl){
int u=q1.front();q1.pop();
int e=q2.front();q2.pop();
// printf(" e:%d\n",e);
if(e==ed){//结束状态
for(;hd>;hd=L2[hd]){ans[++num]=L1[hd];}
for(int i=num;i;i--)printf("%c",ans[i]+'A');
return;
}
for(int i=;i<;i++){
if(!vis[t[u][i]][e|end[t[u][i]]]){
L1[++tl]=i;
L2[tl]=hd;
q1.push(t[u][i]);
q2.push(e|end[t[u][i]]);
vis[t[u][i]][e|end[t[u][i]]]=;
}
}
hd++;
}
}
}ac;
char s[];
int main(){
int i,j;
scanf("%d",&n);
ac.init();
for(i=;i<n;i++)scanf("%s",s),ac.insert(s,i);
// for(i=1;i<=ac.cnt;i++)if(ac.end[i])printf("%d %d\n",i,ac.end[i]);
ac.Build();
ac.solve();
return ;
}

bzoj1195 神奇的ac自动机+状态压缩dp的更多相关文章

  1. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

  2. POJ 3691 (AC自动机+状态压缩DP)

    题目链接:  http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...

  3. hdu 4057(ac自动机+状态压缩dp)

    题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...

  4. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  5. 计蒜客-蒜场抽奖(AC自动机+状态压缩DP)

    题解:题意不再说了,题目很清楚的. 思路:因为N<=10,所以考虑状态压缩 AC自动机中 val[1<<i]: 表示第i个字符串.AC自动机中fail指针是指当前后缀在其他串里面所能 ...

  6. HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )

    题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R. dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态 ...

  7. hdu 2825(ac自动机+状态压缩dp)

    题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...

  8. 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...

  9. Wireless Password - HDU 2825(ac自动机+状态压缩)

    题目大意:有个人想破解他邻居的密码,他邻居告诉了一些关于这个密码的信息,并且给他一个单词集合,他用这些信息判断一下最少有多少种密码. 1->, 所有的密码都是有小写字母组成. 2->,密码 ...

随机推荐

  1. 实验吧 smali文件分析

    题目链接:http://www.shiyanbar.com/ctf/1871 好吧,这题真是基础中的基础,基础中的战斗机. 不光没有任何绕弯的地方,逻辑有且仅有一个.... 多说无益,使用工具jadx ...

  2. java多线程面试题小结

    http://www.importnew.com/12773.html http://www.cnblogs.com/fingerboy/p/5352880.html https://blog.csd ...

  3. python基础-----类和实例

    在python中,首字母大写的名称指的是类,这个类定义中括号的内容是空的. 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板而实例是根据类创建出来的一个个具体 ...

  4. SQL Server - 哈希索引

    转载自:https://blog.csdn.net/josjiang1/article/details/80637076 作者:josjiang1 ————————总结———————— 使用场景: 1 ...

  5. 在Linux环境下使用Apache部署ASP.NET Core

    在前几篇文章中我们一起探讨了如何在Linux环境中安装ASP.NET Core运行时环境及将ASP.NET Core项目部署在Jexus中,这篇文章中我们将探讨如何将ASP.NET Core部署于Ap ...

  6. 数字图像处理的Matlab实现(3)—灰度变换与空间滤波

    第3章 灰度变换与空间滤波(1) 3.1 简介 空间域指的是图像平面本身,这类方法是以对图像像素直接处理为基础的.本章主要讨论两种空间域处理方法:亮度(灰度)变换与空间滤波.后一种方法有时涉及到邻域处 ...

  7. 【转】python模块分析之hashlib加密(二)

    [转]python模块分析之hashlib加密(二) hashlib模块是用来对字符串进行hash加密的模块,明文与密文是一一对应不变的关系:用于注册.登录时用户名.密码等加密使用.一.函数分析:1. ...

  8. iphoneX适配!!!

    方法1.js判断(以下采用Jquery) //适配iphonex && $(window).height() === && window.devicePixelRati ...

  9. Linux 网络侦错:无法联机原因分析

    所谓的软件问题,绝大部分就是 IP 参数设定错误啊,路由不对啊,还有 DNS 的 IP 设定错误等等的, 这些问题都是属于软件设定啦!只要将设定改一改,利用一些侦测软件查一查,就知道问题出在哪里了!基 ...

  10. 【转】vector中erase()的使用注意事项

    vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(   iterator _Whe ...