HDU2825 Wireless Password 【AC自动机】【状压DP】
HDU2825 Wireless Password
Problem Description
Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless network in the building. Liyuan did not know the password of the network, but he got some important information from his neighbor. He knew the password consists only of lowercase 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.
Input
There will be several data sets. Each data set will begin with a line with three integers n m k. n is the length of the password (1<=n<=25), m is the number of the words in the magic word set(0<=m<=10), and the number k denotes that the password included at 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.
Output
For each test case, please output the number of possible passwords MOD 20090717.
Sample Input
10 2 2
hello
world
4 1 1
icpc
10 0 0
0 0 0
Sample Output
2
1
14195065
我觉得挺好的一道题。。一开始只知道是DP,然后写了一个循环,后面发现不能重复计算,然后改成了状压DP,改成了队列实现DP,上线是步数小于等于长度,然后每一次DP转移将步数加1就好了,然后或一下当前存在的状态。
处理fail指针的时候做两个小优化,一个是在处理的时候就把fail链上的id全部统计起来,二个是把失配后跳到的节点直接储存成儿子节点
然后注意开一下取模的操作,防止TLE
#include<bits/stdc++.h>
using namespace std;
#define N 110
#define Mod 20090717
struct Node{
int fail,id,ch[26];
void clean(){
fail=id=0;
memset(ch,0,sizeof(ch));
}
}t[N];
struct Node1{int id,tmp,now;};
int n,m,p,tot=0;
int dp[N][26][1025],c[1025];
bool vis[N][26][1025];
char s[20][N];
void init(){
tot=1;
t[0].clean();t[1].clean();
for(int i=0;i<26;i++)t[0].ch[i]=1;
memset(dp,0,sizeof(dp));
}
int index(char c){return c-'a';}
void insert(char *s,int id){
int len=strlen(s),u=1;
for(int i=0;i<len;i++){
int tmp=index(s[i]);
if(!t[u].ch[tmp])
t[t[u].ch[tmp]=++tot].clean();
u=t[u].ch[tmp];
}
t[u].id=1<<(id-1);
}
void buildFail(){
queue<int> q;q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){
int w=t[u].ch[i],v=t[u].fail;
while(!t[v].ch[i])v=t[v].fail;
v=t[v].ch[i];
if(w){
t[w].fail=v;
t[w].id|=t[v].id;//***
q.push(w);
}else t[u].ch[i]=v;//***
}
}
}
void solve(){
queue<Node1> qn;
qn.push((Node1){1,0,0});
dp[1][0][0]=1;
while(!qn.empty()){
Node1 u=qn.front();qn.pop();
vis[u.id][u.tmp][u.now]=0;
if(u.tmp>n)continue;
for(int i=0;i<26;i++){
int id=t[u.id].ch[i],tmp=u.tmp+1,now=u.now|t[id].id;
dp[id][tmp][now]+=dp[u.id][u.tmp][u.now];
if(dp[id][tmp][now]>Mod)dp[id][tmp][now]-=Mod;
if(!vis[id][tmp][now]){
vis[id][tmp][now]=1;
qn.push((Node1){id,tmp,now});
}
}
}
}
int count(int t){
int ans=0;
while(t){
if(t&1)ans++;
t>>=1;
}
return ans;
}
int main(){
for(int i=0;i<1024;i++)c[i]=count(i);
while(1){
scanf("%d%d%d",&n,&m,&p);
if(!n)break;
init();//初始化
for(int i=1;i<=m;i++){
scanf("%s",s[i]);
insert(s[i],i);
}
buildFail();
solve();
int ans=0,up=1<<m;
for(int i=0;i<up;i++)if(c[i]>=p)
for(int j=1;j<=tot;j++){
ans+=dp[j][n][i];
if(ans>Mod)ans-=Mod;
}
printf("%d\n",ans);
}
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) ...
- 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 ...
随机推荐
- C和C#两种方式实现邮件的简单发送
内容为通过两种方式发送邮件--1.C语言发送邮件 2.C#发送邮件 一,C语言进行邮件的发送 C语言发送邮件的步骤的简单解析: 1.创建TCP连接 socket() 2.连接到邮箱服务器 ...
- 【三小时学会Kubernetes!(零) 】系统结构及相关示例微服务介绍
写在前面 牢牢占据容器技术统治地位的 Kubernetes,其重要性想必不言而喻,我保证本文是最详尽的 Kubernetes 技术文档,从我在后台排版了这么漫长的时间就能看出来.废话不多说 — — 以 ...
- poi解析Excel文件版本问题
poi解析Excel文件时有两种格式: HSSFWorkbook格式用来解析Excel2003(xls)的文件 XSSFWorkbook格式用来解析Excel2007(xlsx)的文件 如果用HSSF ...
- Django框架学习笔记(windows环境下安装)
博主最近开始学习主流框架django 网上大部分的安装环境都linux的 由于博主在windows环境下已经有了 Pycharm编辑器 ,所以决定还是继续在windows环境下学习 首先是下载 链接 ...
- Konva的使用
KonvaJS 快速入门 Konva 是一个 基于 Canvas 开发的 2d js 框架库, 它可以轻松的实现桌面应用和移动应用中的图形交互交互效果. Konva 可以高效的实现动画, 变换, 节点 ...
- 9.深入理解AbstractQueuedSynchronizer(AQS)
1. AQS简介 在上一篇文章中我们对lock和AbstractQueuedSynchronizer(AQS)有了初步的认识.在同步组件的实现中,AQS是核心部分,同步组件的实现者通过使用AQS提供的 ...
- Neutron之OVS
OVS即开放虚拟交换标准,不仅仅是为了支持OpenFlow协议,而是为了给虚拟化平台上运行的虚拟机实例提供一套纯软件实现的路由交换协议栈.具体点说,Open vSwitch是在开源的Apache2.0 ...
- 文件上传及时显示, 前端js和后端php相互结合使用
文件读取 javascript 绑定文件上传变化事件 onchange 利用window对象 FileReader 调用方法 readerAsDataURL onload 方法 异步读取 属性:fil ...
- Sum All Numbers in a Range
我们会传递给你一个包含两个数字的数组.返回这两个数字和它们之间所有数字的和. 最小的数字并非总在最前面. 这是一些对你有帮助的资源: Math.max() Math.min() Array.reduc ...
- lombok --- 常用注解解析
@Data@Getter @Setter @ToString@Cleanup@NonNull@Builder@EqualsAndHashCode