hdu2825

题意

给出一些字符串,要求构造一个长度为 \(n\) 的字符串至少包括其中的 \(k\) 个,问有多少种字符串满足条件。

分析

AC自动机 构造状态转移,然后 状态压缩DP 即可。

\(dp[i][j][k]\) 表示长度为 \(i\) 在 AC自动机上的状态为 \(j\) 已包含的字符串为 \(k\) 时的字符串数量( \(k\) 二进制表示是否有某个给出的字符串)。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int MAXN = 1e2 + 10;
const int MOD = 20090717;
struct Trie {
int root, L, nxt[MAXN][26], fail[MAXN], val[MAXN];
int newnode() {
memset(nxt[L], -1, sizeof nxt[L]);
return L++;
}
void init() {
L = 0;
root = newnode();
memset(val, 0, sizeof val);
memset(fail, 0, sizeof fail);
}
void insert(int id, char S[]) {
int len = strlen(S);
int now = root;
for(int i = 0; i < len; i++) {
int d = S[i] - 'a';
if(nxt[now][d] == -1) nxt[now][d] = newnode();
now = nxt[now][d];
}
val[now] |= (1 << id);
}
void build() {
queue<int> Q;
for(int i = 0; i < 26; i++) {
if(nxt[root][i] == -1) nxt[root][i] = 0;
else { fail[nxt[root][i]] = root; Q.push(nxt[root][i]); }
}
while(!Q.empty()) {
int now = Q.front(); Q.pop();
val[now] |= val[fail[now]];
for(int i = 0; i < 26; i++) {
if(nxt[now][i] == -1) nxt[now][i] = nxt[fail[now]][i];
else { fail[nxt[now][i]] = nxt[fail[now]][i]; Q.push(nxt[now][i]); }
}
}
}
}trie;
int dp[30][MAXN][1024];
int cnt[1024];
int main() {
int n, m, k;
cnt[0] = 0;
for(int i = 1; i < 1024; i++) {
int j = 0;
while(!((i >> j) & 1)) j++;
cnt[i] = cnt[i - (1 << j)] + 1;
}
while(~scanf("%d%d%d", &n, &m, &k) && (n + m + k)) {
trie.init();
for(int i = 0; i < m; i++) {
char s[15];
scanf("%s", s);
trie.insert(i, s);
}
trie.build();
for(int i = 0; i <= n; i++) {
for(int j = 0; j < trie.L; j++) {
for(int k = 0; k < (1 << m); k++) {
dp[i][j][k] = 0;
}
}
}
dp[0][0][0] = 1;
for(int i = 0; i < n; i++) {
for(int j = 0; j < trie.L; j++) {
for(int bit = 0; bit < (1 << m); bit++) {
if(!dp[i][j][bit]) continue;
for(int k = 0; k < 26; k++) {
int tmp = trie.nxt[j][k];
(dp[i + 1][tmp][trie.val[tmp] | bit] += dp[i][j][bit]) %= MOD;
}
}
}
}
int sum = 0;
for(int i = 0; i < trie.L; i++) {
for(int j = 0; j < (1 << m); j++) {
if(cnt[j] >= k) sum = (sum + dp[n][i][j]) % MOD;
}
}
printf("%d\n", sum);
}
return 0;
}

hdu2825(AC 自动机)的更多相关文章

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

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

  2. 【AC自动机】【状压dp】hdu2825 Wireless Password

    f(i,j,S)表示当前字符串总长度为i,dp到AC自动机第j个结点,单词集合为S时的方案数. 要注意有点卡常数,注意代码里的注释. #include<cstdio> #include&l ...

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

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

  4. 【HDU2825】Wireless Password【AC自动机,状态压缩DP】

    题意 题目给出m(m<=10)个单词,每个单词的长度不超过10且仅由小写字母组成,给出一个正整数n(n<=25)和正整数k,问有多少方法可以组成长度为n的文本且最少包含k个给出的单词. 分 ...

  5. 【hdu2825】ac自动机 + 状压dp

    传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...

  6. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  7. AC自动机总结

    AC自动机的模板 void buildAC() { while(!q.empty()) q.pop(); q.push(); while(!q.empty()) { int x=q.front();q ...

  8. 【AC自动机&&Trie图】积累

    以前KMP和后缀系列(主要是后缀数组,后缀自动机),都刷了一定数量的题,但是对于AC自动机,却有些冷落,罪过. 但是我感觉,在蓝桥杯比赛中AC自动机出现的概率比后缀系列大,简单的会考匹配,稍难一点会考 ...

  9. 对AC自动机+DP题的一些汇总与一丝总结 (1)

    (1)题意 : 输入n.m.k意思就是给你 m 个模式串,问你构建长度为 n 至少包含 k 个模式串的方案有多少种 分析:(HDU2825) DP[i][j][k] 表示 DP[第几步][哪个节点结尾 ...

随机推荐

  1. [洛谷P2044][NOI2012]随机数生成器

    题目大意:给你$m,a,c,X_0,n,g$,求$X_{n+1}=(a\cdot X_n+c) \bmod{m}$,最后输出对$g$取模 题解:矩阵快速幂+龟速乘,这里用了$long\;double$ ...

  2. [POJ1631]Bridging signals

    题目大意:不知,根据样例猜测为最长上升子序列(竟然还对了) 题解:$O(n log_2 n)$,求二维偏序,(q为存答案的序列,a存原序列,len为答案) for(int i = 1; i <= ...

  3. 如何用PhotoShop制作网站的favicon.ico

    所谓favicon,即Favorites Icon的缩写,顾名思义,便是其可以让浏览器的收藏夹中除显示相应的标题外,还以图标的方式区别不同的网站.当然,这不仅仅是Favicon的全部,根据浏览器的不同 ...

  4. HDU4185:Oil Skimming(二分图最大匹配)

    Oil Skimming Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. oracle 包和包实现

    包: create or replace package sp_pexam_clear as --定义结构体 /*type re_stu is record( rname student.name%t ...

  6. 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)

    本文属于本人原创,转载请注明出处:http://blog.csdn.net/xxd851116/archive/2009/06/25/4296866.aspx [前面的话] 在网上经常看到有人对req ...

  7. 粉刷匠(bzoj 1296)

    Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...

  8. Nginx反向代理丢失cookie的问题

    今天在测试环境进行测试时发现有个页面无论如何都进不去了,经过调试发现,JSESSIONID的path和我访问应用的工程不相同!我访问的应用是/xxx/,而JSESSIONID的path是/yyy/,这 ...

  9. 【Atcoder】ARC082 E - ConvexScore

    [算法]计算几何 [题意]给定平面直角坐标系上的若干个点,任意选点连成凸多边形,凸多边形的价值定义为2^(n-|S|),其中n为凸多边形内部点数(含边界),|S|为顶点数,求总价值.n<=10^ ...

  10. javascript的阻塞机制

    javascript的阻塞机制 浏览器在执行javascript代码时,不能同时做其它事情,当遇到javascript时,浏览器会下载js文件,解析并执行该文件,而在这期间页面的渲染是完全被阻塞的,因 ...