题意:

给出m个模式串,要求构造一长度为n的文本串,至少包括k种模式串,求有多少种可能的模式串。

k<=10  然后可以想到状压

一个文本串,k种模式串,很容易想到AC自动机。

把所有的模式串放入AC自动机上面,然后跑状压DP

跟AC自动机有关的DP一般都要用的AC自动机上的节点。

dp状态定义为dp[ i ][ j ][status]走到长度为i 时,在AC自动机上 j 这个节点

状态为 status 的方案数。

然后统计答案即可。

由于状态只与上一步有关,所以我滚动了一维,多开一维并不会MLE,也可以写。

 #include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <time.h>
#include <cstring>
#include <iostream>
#include <algorithm> #define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a, b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define sf(n) scanf("%d", &n)
#define sff(a, b) scanf("%d %d", &a, &b)
#define sfff(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FIN freopen("../date.txt","r",stdin)
#define gcd(a, b) __gcd(a,b)
#define lowbit(x) x&-x
#define IO iOS::sync_with_stdio(false) using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 1e6 + ;
const int maxm = 8e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = ; char buf[];
int n, m, k;
LL dp[][][]; int cal(int num) {
int ans = ;
while (num) {
if (num % ) ans++;
num /= ;
}
return ans;
} struct Aho_Corasick {
int next[][], fail[], End[];
int root, cnt; int newnode() {
for (int i = ; i < ; i++) next[cnt][i] = -;
End[cnt++] = ;
return cnt - ;
} void init() {
cnt = ;
root = newnode();
} void insert(char buf[], int id) {
int len = strlen(buf);
int now = root;
for (int i = ; i < len; i++) {
if (next[now][buf[i] - 'a'] == -) next[now][buf[i] - 'a'] = newnode();
now = next[now][buf[i] - 'a'];
}
End[now] |= ( << id);
} void build() {
queue<int> Q;
fail[root] = root;
for (int i = ; i < ; i++)
if (next[root][i] == -) next[root][i] = root;
else {
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while (!Q.empty()) {
int now = Q.front();
Q.pop();
End[now] |=End[fail[now]];
for (int i = ; i < ; i++)
if (next[now][i] == -) next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
} void debug() {
for (int i = ; i < cnt; i++) {
printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
for (int j = ; j < ; j++) printf("%2d", next[i][j]);
printf("]\n");
}
}
} ac; int main() {
// FIN;
while (~sfff(n, m, k)) {
if (n == && m == && k == ) break;
ac.init();
for (int i = ; i < m; ++i) {
scanf("%s", buf);
ac.insert(buf, i);
}
ac.build();
for (int i = ; i <; i++)
for (int j = ; j < ac.cnt; j++)
for (int p = ; p < ( << m); p++)
dp[i][j][p] = ;
int now = ;
dp[now][][] = ;
for (int i = ; i <= n; ++i) {
now = now ^ ;
for (int j = ; j < ac.cnt; j++)
for (int p = ; p < ( << m); p++)
dp[now][j][p] = ;
for (int j = ; j < ac.cnt; ++j) {
for (int status = ; status < ( << m); ++status) {
if (dp[now ^ ][j][status]) {
for (int l = ; l < ; ++l) {
int st = (status | ac.End[ac.next[j][l]]);
dp[now][ac.next[j][l]][st] = (dp[now][ac.next[j][l]][st] + dp[now ^ ][j][status]) % mod;
}
}
}
}
}
LL ans = ;
for (int status = ; status < ( << m); ++status) {
if (cal(status) < k) continue;
for (int i = ; i < ac.cnt; ++i)
ans = (ans + dp[now][i][status]) % mod;
}
printf("%lld\n", ans);
}
return ;
}

Wireless Password HDU - 2825的更多相关文章

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

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

  2. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

  3. hdu 2825 Wireless Password(ac自己主动机&amp;dp)

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

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

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

  5. 【HDU2825】Wireless Password (AC自动机+状压DP)

    Wireless Password Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u De ...

  6. HDU2825 Wireless Password 【AC自动机】【状压DP】

    HDU2825 Wireless Password Problem Description Liyuan lives in a old apartment. One day, he suddenly ...

  7. HDU2825 Wireless Password —— AC自动机 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others)    ...

  8. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  9. HDU - 2825 Wireless Password (AC自动机+状压DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数. 题解: ...

随机推荐

  1. .net API跨域

    在webconfig中的节点 <system.webServer> </system.webServer> 下添加 <httpProtocol><custom ...

  2. sqoop导出数据|Hive|HDFS和脚本编写

    导出数据 在Sqoop中,“导出”概念指:从大数据集群(HDFS,HIVE,HBASE)向非大数据集群(RDBMS)中传输数据,叫做:导出,即使用export关键字. HIVE/HDFS到RDBMS ...

  3. 探索NDIS HOOK新的实现方法(1)

    NDIS HOOK是专业级防火墙使用的一种拦截技术,NDIS HOOK的重点是如何获得特定协议对应NDIS_PROTOCOL_BLOCK指针,获得了该指针,接下来就可以替换该协议所注册的收发函数,而达 ...

  4. iBATIS存储过程

    使用iBATIS配置来调用存储过程.为了理解这一章,首先需要了解我们是如何在MySQL中创建一个存储过程. 在继续对本章学习之前,可以通过MySQL存储过程. 我们已经在MySQL下有EMPLOYEE ...

  5. Array类型中的检测数组,转换方法,栈方法,队列方法

    我的新博客==> http://www.suanliutudousi.com/2017/08/24/array%E7%B1%BB%E5%9E%8B%E4%B8%AD%E7%9A%84%E6%A3 ...

  6. BeanShell Sampler生成uuid

  7. 7.springboot+mybatis+redis整合

    选择生成的依赖 选择保存的工程路径 查询已经生成的依赖,并修改mysql的版本 <dependencies> <dependency> <groupId>org.s ...

  8. mysql分区partition详解

    分区管理  论坛 1. RANGE和LIST分区的管理 针对非整形字段进行RANG\LIST分区建议使用COLUMNS分区.  RANGE COLUMNS是RANGE分区的一种特殊类型,它与RANGE ...

  9. css 写一个向右的箭头

    经常写移动端页面时会用到向右的箭头,之前都是用图片,突然想到用css应该也能写,于是一搜还确实有 width: 7px; height: 7px; border-top: 2px solid #fff ...

  10. SpringMVC常用注解知识总结

    1.@Controller 注解到类名上,表示该类是控制器. 2.@RequestMapping("/xxxx") 可以放在类名/方法名之上,表示访问请求该方法时的url.如果该方 ...