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的串,如果 ...
随机推荐
- 【审核】检查iOS项目中是否使用了IDFA
(1)什么是IDFA 关于IDFA,在提交应用到App Store时,iTunes Connect有如下说明: 这里说到检查项目中是否包含IDFA,那如何来对iOS项目(包括第三方SDK)检查是否包含 ...
- iOS开发-简单的循环结构分析
1.while循环 while (循环条件) { 循环体: } // 1.定义循环变量 ; // 2.循环条件 ) { // 3.循环体 printf("%d\n" ...
- segmentedControl设置字体和字体颜色问题
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor blackColor],UITextAttributeT ...
- aws中的路由表
参考官方文档: 由表中包含一系列被称为路由的规则,可用于判断网络流量的导向目的地. 在您的 VPC 中的每个子网必须与一个路由表关联:路由表控制子网的路由.一个子网一次只能与一个路由表关联,但您可以将 ...
- MSSQL 2000 错误823恢复案例
一.故障描述 MSSQL Server 2000 附加数据库错误823,附加数据库失败.数据库没有备份,不能通过备份恢复数据库,急需恢复数据库中的数据. 二.故障分析SQL Server数据库 823 ...
- 调用WCF时,调用已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定。
解决方案: 其实只要在客户端配置文件中加上如下紫色粗体属性( maxReceivedMessageSize): <?xml version="1.0" encoding=&q ...
- New UWP Community Toolkit - DeveloperTools
概述 UWP Community Toolkit 中有一个开发者工具集 DeveloperTools,可以帮助开发者在开发过程中进行 UI 和功能的调试,本篇我们结合代码详细讲解 Develope ...
- 你考虑清楚了吗就决定用 Bootstrap ?
近年来,在前端项目中, Bootstrap 已经成为了一个非常受欢迎的工具. Bootstrap 的确有很多优点,然而,如果你的团队中恰好有一个专职的前端工程师.那我推荐你们不要使用 Bootstra ...
- zuul入门(1)zuul 的概念和原理
一.zuul是什么 zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架. ...
- java实现两个int数交换
普通方法,进阶方法,大神方法 @Test public void test3(){ int m = 5; int n = 12; //要求m和n交换位置 System.out.println(&quo ...