HDU2825 Wireless Password —— AC自动机 + 状压DP
题目链接:https://vjudge.net/problem/HDU-2825
Wireless Password
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7733 Accepted Submission(s): 2509
For instance, say that you know that the password is 3 characters long, and the magic word set includes 'she' and 'he'. Then the possible password is only 'she'.
Liyuan wants to know whether the information is enough to reduce the number of possible passwords. To answer this, please help him write a program that determines the number of possible passwords.
hello
world
4 1 1
icpc
10 0 0
0 0 0
1
14195065
题意:
给出m个单词,问长度为n且至少含有k个单词的字符串有多少个?
题解:
1.把这m个单词插入到AC自动机中。
2.设dp[i][j][status]为:长度为i,到达j状态(AC自动机中的状态),且含有单词的信息为status(状态压缩)的字符串有多少个。
3.模拟在AC自动机上的跳动,求出dp数组。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = ;
const int MAXN = +; int num[<<], dp[][][<<]; struct Trie
{
const static int sz = , base = 'a';
int next[MAXN][sz], fail[MAXN], end[MAXN];
int root, L;
int newnode()
{
for(int i = ; i<sz; i++)
next[L][i] = -;
end[L++] = ;
return L-;
}
void init()
{
L = ;
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]-base] == -) next[now][buf[i]-base] = newnode();
now = next[now][buf[i]-base];
}
end[now] |= (<<id);
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ; i<sz; 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<sz; 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]);
}
}
} int query(int n, int m, int k)
{
for(int i = ; i<=n; i++)
for(int j = ; j<L; j++)
for(int s = ; s<(<<m); s++)
dp[i][j][s] = ;
dp[][][] = ;
for(int i = ; i<n; i++) //模拟在AC自动机上的跳动
for(int j = ; j<L; j++)
for(int s = ; s<(<<m); s++)
{
if(dp[i][j][s]==) continue;
for(int p = ; p<sz; p++)
{
int newi = i+;
int newj = next[j][p];
int news = (s|end[newj]);
dp[newi][newj][news] += dp[i][j][s];
dp[newi][newj][news] %= MOD;
}
}
int ret = ;
for(int s = ; s<(<<m); s++)
{
if(num[s]<k) continue;
for(int i = ; i<L; i++)
ret = (ret+dp[n][i][s])%MOD;
}
return ret;
}
}; Trie ac;
char buf[];
int main()
{
for(int s = ; s<(<<); s++)
{
num[s] = ;
for(int i = ; i<; i++)
if(s&(<<i)) num[s]++;
} int n, m, k;
while(scanf("%d%d%d", &n,&m,&k)&&(n||m||k))
{
ac.init();
for(int i = ; i<m; i++)
{
scanf("%s", buf);
ac.insert(buf, i);
}
ac.build();
int ans = ac.query(n,m,k);
printf("%d\n", ans);
}
return ;
}
HDU2825 Wireless Password —— AC自动机 + 状压DP的更多相关文章
- hdu2825 Wireless Password(AC自动机+状压dp)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- HDU-2825 Wireless Password(AC自动机+状压DP)
题目大意:给一系列字符串,用小写字母构造出长度为n的至少包含k个字符串的字符串,求能构造出的个数. 题目分析:在AC自动机上走n步,至少经过k个单词节点,求有多少种走法. 代码如下: # includ ...
- 【HDU2825】Wireless Password (AC自动机+状压DP)
Wireless Password Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u De ...
- hdu_2825_Wireless Password(AC自动机+状压DP)
题目链接:hdu_2825_Wireless Password 题意: 给你m个串,问长度为n至少含k个串的字符串有多少个 题解: 设dp[i][j][k]表示考虑到长度为i,第j个自动机的节点,含有 ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】
题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...
- HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解
题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
Time Limit: 10 Seconds Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...
- hdu 4057--Rescue the Rabbit(AC自动机+状压DP)
题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...
随机推荐
- 2017.2.16 开涛shiro教程-第十七章-OAuth2集成(二)客户端
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第十七章-OAuth2集成 3.客户端 客户端 ...
- JAVA Eclipse ActivityManager Warning Activity not started, its current task has been brought to the front怎么办
Eclipse运行提示Activity not started,因为当前程序已经在运行,需要退出当前程序再测试
- URAL1306 Sequence Median(卡内存神题)
给出n个数,n<=250000,求这n个数的中位数,内存限制1mb 卡内存的神题,用数组存下来刚好1mb,再加上执行时消耗内存.立即爆. 因此我们用优先队列存储一半的数. 网上的某些代码,用pr ...
- Shell脚本之:数组
bash支持一维数组,并且没有限定数组的大小,数组元素的下标由0开始编号. 定义数组 在Shell中,用括号来表示数组,数组元素用“空格”符号分割开.定义数组的一般形式为: array_name=(v ...
- JSP简单练习-用Servlet获取表单数据
// javaBean代码 package servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.* ...
- git 操作分支
1. git 查看本地分支:git branch 2. git 查看所有分支:git branch -a 3. git 新建本地分支:git branch branchName 4. git 新建分支 ...
- Hibernate学习一----------Hibernate初实现
© 版权声明:本文为博主原创文章,转载请注明出处 ORM(Object/Relationship Mapping):对象/关系映射 - 利用面向对象思想编写的数据库应用程序最终都是把对象信息保存在关系 ...
- Jquery EasyUI弹出窗体
$("#btnCreate").click(function () { $("#modalwindow").html("<iframe widt ...
- kaptcha的和springboot一起使用的简单例子
https://blog.csdn.net/xiaoyu19910321/article/details/79296030
- oracle角色(role)概念
一个角色是一组特权,它可以授权给用户或其它角色. 特权有:create table,select on boss ,create session,insert on boss,update on bo ...