hdu2825(AC 自动机)
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 自动机)的更多相关文章
- 【HDU2825】Wireless Password (AC自动机+状压DP)
Wireless Password Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u De ...
- 【AC自动机】【状压dp】hdu2825 Wireless Password
f(i,j,S)表示当前字符串总长度为i,dp到AC自动机第j个结点,单词集合为S时的方案数. 要注意有点卡常数,注意代码里的注释. #include<cstdio> #include&l ...
- HDU2825 Wireless Password —— AC自动机 + 状压DP
题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others) ...
- 【HDU2825】Wireless Password【AC自动机,状态压缩DP】
题意 题目给出m(m<=10)个单词,每个单词的长度不超过10且仅由小写字母组成,给出一个正整数n(n<=25)和正整数k,问有多少方法可以组成长度为n的文本且最少包含k个给出的单词. 分 ...
- 【hdu2825】ac自动机 + 状压dp
传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...
- AC自动机基础知识讲解
AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...
- AC自动机总结
AC自动机的模板 void buildAC() { while(!q.empty()) q.pop(); q.push(); while(!q.empty()) { int x=q.front();q ...
- 【AC自动机&&Trie图】积累
以前KMP和后缀系列(主要是后缀数组,后缀自动机),都刷了一定数量的题,但是对于AC自动机,却有些冷落,罪过. 但是我感觉,在蓝桥杯比赛中AC自动机出现的概率比后缀系列大,简单的会考匹配,稍难一点会考 ...
- 对AC自动机+DP题的一些汇总与一丝总结 (1)
(1)题意 : 输入n.m.k意思就是给你 m 个模式串,问你构建长度为 n 至少包含 k 个模式串的方案有多少种 分析:(HDU2825) DP[i][j][k] 表示 DP[第几步][哪个节点结尾 ...
随机推荐
- [Leetcode] remove nth node from the end of list 删除链表倒数第n各节点
Given a linked list, remove the n th node from the end of list and return its head. For example, Giv ...
- 创建dll
在制作dll的时候,如果全局变量不导出,而函数调用中,包含了全局变量,那么会出现全局变量没有值的问题. add.c #pragma once //强制无签名utf-8 #include "a ...
- Active Directory Domain Services in Windows Server 2016/2012
Applies To: Windows Server 2016, Windows Server 2012 R2, Windows Server 2012 You will find links to ...
- 怎样在WPS上实现代码语法高亮
转载自:http://www.cnblogs.com/yuphone/archive/2009/12/13/1622901.html 小時不識月 Stupid & Hungry 本文列举两种可 ...
- 2017年上海金马五校程序设计竞赛:Problem A : STEED Cards (STL全排列函数)
Description Corn does not participate the STEED contest, but he is interested in the word "STEE ...
- [bzoj3990][SDOI2015]排序-搜索
Brief Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<= ...
- [Leetcode Week2]Sort Colors
Sort Colors题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/sort-colors/description/ Description Give ...
- linux设备驱动中的并发控制【转】
转自:http://www.cnblogs.com/plinx/archive/2013/01/28/2873121.html 在linux内核中,主要的静态发生于以下几种情况: 1.对称多处理器(S ...
- chromium源代码下载(Win7x64+VS2013sp2, 39.0.2132.2)
chromium源代码下载(Win7x64+VS2013sp2, 39.0.2132.2) http://www.aichengxu.com/diannao/1000251.htm 前后折腾了四天,当 ...
- 【反演复习计划】【bzoj2820】YY的GCD
这题跟2818一样的,只不过数据水一点,可以用多一个log的办法水过去…… 原题意思是求以下式子:$Ans=\sum\limits_{isprime(p)}\sum\limits_{i=1}^{a}\ ...