hdu 2825 aC自动机+状压dp
Wireless Password
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5640 Accepted Submission(s): 1785
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.
world
/*
hdu 2825 aC自动机+状压dp 给你m个子串,求长度为n的主串中至少出现k个子串的方案数
首先通过AC自动机构建关系图. 然后用dp解决状态转移,需要知道用过哪些子串
因为k比较小,我们直接转换成二进制来记录当前状态包含了哪些子串。用ed对各子串进行标记 dp[i][j][t]就表示长度为i,当前位置上是j时,所包含子串的情况t hhh-2016-04-24 17:13:36
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef unsigned long long ll;
typedef unsigned int ul;
const int mod = 20090717;
const int INF = 0x3f3f3f3f;
int tot;
int dp[30][111][1<<10]; struct Matrix
{
int len;
int ma[111][111];
Matrix() {};
Matrix(int L)
{
len = L;
}
}; struct Tire
{
int nex[110][26],fail[110],ed[110];
int root,L;
int newnode()
{
for(int i = 0; i < 26; i++)
nex[L][i] = -1;
ed[L++] = 0;
return L-1;
} void ini()
{
L = 0,root = newnode();
} int cal(char ch)
{
if(ch == 'A')
return 0;
else if(ch == 'C')
return 1;
else if(ch == 'G')
return 2;
else if(ch == 'T')
return 3;
} void inser(char buf[],int id)
{
int len = strlen(buf);
int now = root;
for(int i = 0; i < len; i++)
{
int ta = buf[i] - 'a';
if(nex[now][ta] == -1)
nex[now][ta] = newnode();
now = nex[now][ta];
}
ed[now] |= (1<<id);
} void build()
{
queue<int >q;
fail[root] = root;
for(int i = 0; i < 26; i++)
if(nex[root][i] == -1)
nex[root][i] = root;
else
{
fail[nex[root][i]] = root;
q.push(nex[root][i]);
}
while(!q.empty())
{
int now = q.front();
q.pop();
if(ed[fail[now]])
ed[now] |= ed[fail[now]];
for(int i = 0; i < 26; i++)
{
if(nex[now][i] == -1)
nex[now][i] = nex[fail[now]][i];
else
{
fail[nex[now][i]] = nex[fail[now]][i];
q.push(nex[now][i]);
}
}
}
} Matrix to_mat()
{
Matrix mat(L);
memset(mat.ma,0,sizeof(mat.ma));
for(int i = 0; i < L; i++)
{
for(int j = 0; j < 4; j++)
{
if(!ed[nex[i][j]])
mat.ma[i][nex[i][j]] ++;
}
}
return mat;
}
}; //Matrix mat;
Tire ac;
char buf[22]; void debug()
{
Matrix t = ac.to_mat();
for(int i = 0; i < t.len; i++)
{
for(int j = 0; j < 26; j++)
{
printf("%d ",t.ma[i][ac.nex[i][j]]);
}
printf("\n");
}
} int num[1<<10]; int main()
{
for(int i=0; i<(1<<10); i++)
{
num[i] = 0;
for(int j = 0; j < 10; j++)
if(i & (1<<j))
num[i]++;
}
int n,m,p;
while(scanf("%d%d%d",&n,&m,&p) != EOF)
{
if(!n && !m && !p)
break;
ac.ini();
for(int i = 0; i < m; i++)
{
scanf("%s",buf);
ac.inser(buf,i);
}
ac.build();
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <ac.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 < 2; i++)
{
for(int j = 0; j < ac.L; j++)
{
for(int t = 0; t < (1<<m); t++)
{
if(dp[i][j][t] > 0)
for(int k = 0; k < 26; k++)
{
int nexi = i+1;
int nexj = ac.nex[j][k];
int nexk = (t|ac.ed[nexj]);
dp[nexi][nexj][nexk] = (dp[nexi][nexj][nexk] + dp[i][j][t])%mod; }
}
}
}
int ans = 0;
for(int j = 0; j < (1<<m); j++)
{
if(num[j] < p)
continue;
for(int i = 0; i < ac.L; i++)
ans = (ans+dp[n][i][j])%mod;
}
printf("%d\n",ans);
}
return 0;
}
hdu 2825 aC自动机+状压dp的更多相关文章
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解
题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...
- hdu 4057--Rescue the Rabbit(AC自动机+状压DP)
题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...
- BZOJ1559 [JSOI2009]密码 【AC自动机 + 状压dp】
题目链接 BZOJ1559 题解 考虑到这是一个包含子串的问题,而且子串非常少,我们考虑\(AC\)自动机上的状压\(dp\) 设\(f[i][j][s]\)表示长度为\(i\)的串,匹配到了\(AC ...
- zoj3545Rescue the Rabbit (AC自动机+状压dp+滚动数组)
Time Limit: 10 Seconds Memory Limit: 65536 KB Dr. X is a biologist, who likes rabbits very much ...
- 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)题解
题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...
- hdu 6086 -- Rikka with String(AC自动机 + 状压DP)
题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...
- HDU 4057:Rescue the Rabbit(AC自动机+状压DP)***
http://acm.hdu.edu.cn/showproblem.php?pid=4057 题意:给出n个子串,串只包含‘A’,'C','G','T'四种字符,你现在需要构造出一个长度为l的串,如果 ...
随机推荐
- python 操作Memcached
启动Memcached memcached -d -m 10 -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid 参数说明: -d ...
- Flask 学习 六 大型程序结构
pip freeze >requirement.txt 自动生成版本号 pip install -r requirement.txt 自动下载对应的库 梳理结构 config.py #!/usr ...
- 码农、黑客和2B程序员之间的区别
码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L<<32 ...
- Mybatis框架入门
Mybaits框架 一.什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了googl ...
- angular2 学习笔记 の 移动端开发 ( 手势 )
更新 : 2018-01-31 (hammer 的坑) hammer 的 pinch 在某种情况下会自动触发 panEnd,很奇葩. 解决方法就是记入时间呗 refer : https://githu ...
- api-gateway实践(07)新服务网关 - 手动发布
应用地址:http://10.110.20.191:8080/api-gateway-engine/ 一.准备工作 1.xshell登陆云主机 1.1.配置链接 1.2.链接成功 1.3.关闭防火墙 ...
- 阿里云API网关(15)监控预警
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- IDE-Android Studio 导入Ecplise项目不改变结构
Android Studio 导入 Ecplise创建的android 项目 无导入 不修改目录结构 首先,Ecplise 原有目录结构创建的android项目一枚 Sept 1 . 打开项目 S ...
- Tesseract-OCR4.0识别中文与训练字库实例
关于中文的识别,效果比较好而且开源的应该就是Tesseract-OCR了,所以自己亲身试用一下,分享到博客让有同样兴趣的人少走弯路. 文中所用到的身份证图片资源是百度找的,如有侵权可联系我删除. 一. ...
- python API验证
API验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 API验证: a. 发令牌: 静态 PS: 隐患 key ...