建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接暴搜答案. 数据范围很小, 可以AC(复杂度懒得算了....)

------------------------------------------------------------------------------------------------

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
#define b(x) (1 << (x))
#define C(c) (c - 'a')
 
const int maxn = 11;
 
int L, N, Com[maxn][maxn], lth[maxn], V[maxn], R[45], cnt;
ll dp[2][100][b(maxn)];
char S[maxn][maxn], res[45][30];
bool F[maxn];
 
struct Node {
Node *ch[26], *f;
int Id, n;
} pool[100], *pt = pool, *Root, *q[100];
 
void Init() {
scanf("%d%d", &L, &N);
(Root = pt++)->Id = 0;
int idn = Root->n = 0;
for(int i = 0; i < N; i++) {
scanf("%s", S[i]);
lth[i] = strlen(S[i]);
Node* t = Root;
for(int j = 0; j < lth[i]; j++) {
if(!t->ch[C(S[i][j])]) {
pt->Id = ++idn, pt->n = 0;
t->ch[C(S[i][j])] = pt++;
}
t = t->ch[C(S[i][j])];
}
t->n |= b(i);
}
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++) {
int &v = Com[i][j];
for(v = min(lth[i], lth[j]); v; v--) {
bool F = true;
int a = lth[i] - v, b = 0;
while(a < lth[i]) {
if(S[i][a] != S[j][b]) {
F = false;
break;
}
a++, b++;
}
if(F) break;
}
}
cnt = 0;
}
 
void Build() {
int h = 0, t = 0;
(q[t++] = Root)->f = NULL;
while(h < t) {
Node* o = q[h++];
for(int i = 0; i < 26; i++) if(o->ch[i]) {
Node* f = o->f;
while(f && !f->ch[i]) f = f->f;
o->ch[i]->f = f ? f->ch[i] : Root;
q[t++] = o->ch[i];
}
}
}
 
void DFS(int x, int len) {
if(x == N) {
if(len == L) {
int p = 0;
for(int i = 0; i < N; i++)
for(int j = i ? Com[V[i - 1]][V[i]] : 0; j < lth[V[i]]; j++)
res[cnt][p++] = S[V[i]][j];
cnt++;
}
return;
}
for(int i = 0; i < N; i++) if(!F[i]) {
F[V[x] = i] = true;
DFS(x + 1, len + lth[i] - Com[V[x - 1]][i]);
F[i] = false;
}
}
 
bool Cmp(const int &l, const int &r) {
return strcmp(res[l], res[r]) < 0;
}
 
void Work() {
int c = 0, p = 1, h = 0, t = 0, S = b(N) - 1;
q[t++] = Root;
while(h < t) {
Node* o = q[h++];
if(o->f) o->n |= o->f->n;
for(int i = 0; i < 26; i++)
if(o->ch[i]) q[t++] = o->ch[i];
}
memset(dp[c], 0, sizeof dp[c]);
dp[c][0][0] = 1;
for(int i = 0; i < L; i++) {
swap(c, p);
memset(dp[c], 0, sizeof dp[c]);
for(int r = 0; r < t; r++)
for(int s = b(N); s--; ) if(dp[p][q[r]->Id][s]) {
for(int j = 0; j < 26; j++) {
Node* o = q[r];
while(o && !o->ch[j]) o = o->f;
o = o ? o->ch[j] : Root;
dp[c][o->Id][s | o->n] += dp[p][q[r]->Id][s];
}
}
}
ll ans = 0;
for(int i = 0; i < t; i++)
ans += dp[c][q[i]->Id][S];
printf("%lld\n", ans);
if(ans > 42) return;
memset(F, 0, sizeof F);
for(int i = 0; i < N; i++)
F[V[0] = i] = true, DFS(1, lth[i]), F[i] = false;
for(int i = 0; i < ans; i++) 
res[R[i] = i][L] = '\0';
sort(R, R + ans, Cmp);
for(int i = 0; i < ans; i++)
printf("%s\n", res[R[i]]);
}
 
int main() {
Init();
Build();
Work();
return 0;
}

-----------------------------------------------------------------------------------------------

1559: [JSOI2009]密码

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 675  Solved: 213
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

10 2
hello
world

Sample Output

2
helloworld
worldhello

HINT

Source

BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )的更多相关文章

  1. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  2. BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】

    题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...

  3. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  4. zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)

    Time Limit: 10 Seconds      Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...

  5. hdu2825 Wireless Password(AC自动机+状压dp)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  6. hdu 4057--Rescue the Rabbit(AC自动机+状压DP)

    题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...

  7. [BZOJ1559]密码 AC自动机+状压

    问题 K: [JSOI2009]密码 时间限制: 1 Sec  内存限制: 64 MB 题目描述 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝 ...

  8. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  9. UVALive - 4126 Password Suspects (AC自动机+状压dp)

    给你m个字符串,让你构造一个字符串,包含所有的m个子串,问有多少种构造方法.如果答案不超过42,则按字典序输出所有可行解. 由于m很小,所以可以考虑状压. 首先对全部m个子串构造出AC自动机,每个节点 ...

随机推荐

  1. hdu4740【杭州网赛、模拟、有点搜索?】

    当时看了这题就感觉so easy...  本来不想写的,后来感觉是不是可以练一下搜索水平.. 比赛时有人过了就没写.       比赛完了写一下. 实现还不是那么顺利,  囧 本来自己以为这题能练下搜 ...

  2. HDU1506_Largest Rectangle in a Histogram

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  3. CentOS安装maven3.2.2(Linux系列适用)

    首先,下载最新的maven3.2.2,地址:http://mirrors.cnnic.cn/apache/maven/maven-3/3.2.2/binaries/apache-maven-3.2.2 ...

  4. 应用程序无法启动,因为应用程序的并行配置不正确,有关详细信息,请参阅应用程序事件日志,或使用命令行SxsTrace.exe工具

    今天做项目,需要用C#引用C++的链接库文件,但是在调试的时候会报错这个错误. 运行SxsTrace.exe 以管理员用户登陆,启动cmd; 执行命令:SxsTrace Trace -logfile: ...

  5. js——cookie

    cookie:存储数据,当用户访问了某个网站(网页)的时候,我们就可以通过cookie来向访问者电脑上存储数据 1.不同的浏览器存放的cookie位置不一样,也是不能通用的 2. cookie的存储是 ...

  6. 摩根斯坦利 - 2016年09月8日 面试题 - HashMap

    摩根斯坦利 - 2016年09月8日 面试题: 给定一个 Map<Person, Object> map = new HashMap<Person, Object>(); 放入 ...

  7. 进程间通信机制IPC

    进程通信是指进程之间的信息交换.PV操作是低级通信方式,例如信号量,主要是进程间以及同一进程内不同线程之间的同步手段.髙级通信方式是指以较高的效率传输大量数据的通信方式.高级通信方法主要有以下三个类. ...

  8. [多线程同步练习]PV操作

    看一个较为复杂的生产者-消费者问题: 问题描述 桌子上有一只盘子,每次只能向其中放入一个水果.爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果.只有盘子为空时 ...

  9. Java学习之网络编程实例

    转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 多谢分享 网络编程 网络编程对于很多的初学者来说,都是很向往的一 ...

  10. javascript 动态创建表格

    <html> <head> <script> function createTable(rows,lines){ this.rows=rows; this.line ...