hdu2825 Wireless Password(AC自动机+状压dp)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5400 Accepted Submission(s): 1704
letters 'a'-'z', and he knew the length of the password. Furthermore, he got a magic word set, and his neighbor told him that the password included at least k words of the magic word set (the k words in the password possibly overlapping).
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.
least k words of the magic set. This is followed by m lines, each containing a word of the magic set, each word consists of between 1 and 10 lowercase letters 'a'-'z'. End of input will be marked by a line with n=0 m=0 k=0, which should not be processed.
hello
world
4 1 1
icpc
10 0 0
0 0 0
1
14195065
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 505
#define maxnode 205
#define MOD 20090717
int dp[30][105][1050];
struct trie{
int sz,root,val[maxnode],next[maxnode][30],fail[maxnode];
int q[1111111];
void init(){
int i;
sz=root=0;
val[0]=0;
for(i=0;i<26;i++){
next[root][i]=-1;
}
}
int idx(char c){
return c-'a';
}
void charu(char *s,int index){
int i,j,u=0;
int len=strlen(s);
for(i=0;i<len;i++){
int c=idx(s[i]);
if(next[u][c]==-1){
sz++;
val[sz]=0;
next[u][c]=sz;
u=next[u][c];
for(j=0;j<26;j++){
next[u][j]=-1;
}
}
else{
u=next[u][c];
}
}
val[u]|=(1<<index-1);
}
void build(){
int i,j;
int front,rear;
front=1;rear=0;
for(i=0;i<26;i++){
if(next[root][i]==-1 ){
next[root][i]=root;
}
else{
fail[next[root][i] ]=root;
rear++;
q[rear]=next[root][i];
}
}
while(front<=rear){
int x=q[front];
val[x]|=val[fail[x] ];
front++;
for(i=0;i<26;i++){
if(next[x][i]==-1){
next[x][i]=next[fail[x] ][i];
}
else{
fail[next[x][i] ]=next[fail[x] ][i];
rear++;
q[rear]=next[x][i];
}
}
}
}
}ac;
int panduan(int state,int k){
int i,j,num;
num=0;
while(state){
if(state%2==1)num++;
state>>=1;
}
if(num>=k)return 1;
return 0;
}
int main()
{
int n,m,i,j,k,state,state1,ii,jj,t;
char s[20];
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if(n==0 && m==0 && k==0)break;
ac.init();
for(i=1;i<=m;i++){
scanf("%s",s);
ac.charu(s,i);
}
ac.build();
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(i=0;i<=n-1;i++){
for(j=0;j<=ac.sz;j++){
for(state=0;state<=((1<<m)-1);state++ ){
if(dp[i][j][state]){
for(t=0;t<26;t++){
int ii=i+1;
int jj=ac.next[j][t];
int state1=(state| ac.val[ac.next[j][t] ] );
dp[ii][jj][state1]=(dp[ii][jj][state1]+dp[i][j][state])%MOD;
}
}
}
}
}
int sum=0;
for(state=0;state<=((1<<m)-1);state++){
if(panduan(state,k)){
for(j=0;j<=ac.sz;j++){
sum+=dp[n][j][state];
sum%=MOD;
}
}
}
printf("%d\n",sum);
}
return 0;
}
hdu2825 Wireless Password(AC自动机+状压dp)的更多相关文章
- HDU2825 Wireless Password —— AC自动机 + 状压DP
题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others) ...
- 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 ...
随机推荐
- OGG类异常汇总
1.启动ogg后,进程不ABEND也不向前走 原因:ogg启动后,会收集表的统计信息耗费大量时间,导致进程不往前走 解决:在参数文件中加入 SQLEXEC 'alter session set OPT ...
- oracle 释放表空间到OS(resize)
1.查看表空间里面的对象 SELECT OWNER AS OWNER, SEGMENT_NAME AS SEGMENT_NAME, SEGMENT_TYPE AS SEGMENT_TYPE, SUM ...
- 迈凯伦765LT/600LT/720S/650S/570S维修手册电路图Mclaren车间手册接线图
全套迈凯伦维修手册电路图Mclaren车间手册线路图:语言:English,German,French,Spanish,Chinese,Japanese.McLaren迈凯伦新GT维修手册电路图零配件 ...
- 安装JDK与卸载JDK教程
卸载JDK 删除JDK的安装目录,也就是删除了主程序(通过环境变量可以找到) 删除java_home的环境变量 删除环境变量path中与java_home相关的 通过DOS命令cmd来检验是否卸载成功 ...
- Django orm中related_name/related_query_name区别
related_name/related_query_name区别 class Department(models.Model): title = models.CharField(verbose_n ...
- 转 9 jmeter之检查点
9 jmeter之检查点 jmeter有类似loadrunner检查点的功能,就是断言中的响应断言. 1.响应断言(对返回文字结果进行相应的匹配)右击请求-->添加-->断言--> ...
- ubuntu安装mysql5.6
安装mysql5.6在ubuntu上安装mysql5.6的版本 1.添加mysql5.6的源 sudo apt-get install software-properties-common sudo ...
- 13 | 实战:单机如何实现管理百万主机的心跳服务? https://time.geekbang.org/column/article/240656
13 | 实战:单机如何实现管理百万主机的心跳服务? https://time.geekbang.org/column/article/240656
- Building a Robust Live Reloader with WebSockets and Go — Brandur Leach https://brandur.org/live-reload
Building a Robust Live Reloader with WebSockets and Go - Brandur Leach https://brandur.org/live-relo ...
- HDFS HBase Solr Which one? 从访问模式角度决策
HDFS 压缩性能最优.扫描速度最快:不支持随机访问,仅支持昂贵.复杂的文件查询 HBase适合随机访问 Solr 适合检索需求 HBase访问单个记录的时间为毫秒级别,而HDFS不支持随机访问. H ...