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的串,如果 ...
随机推荐
- Linux进程间通信--信号量
信号量绝对不同于信号,一定要分清,关于信号,上一篇博客中已经说过,如有疑问,请移驾! 信号量 一.是什么 信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件 ...
- python自动发邮件
from email.header import Header from email.mime.text import MIMEText from email.utils import parsead ...
- JAVA_SE基础——15.循环嵌套
嵌套循环是指在一个循环语句的循环体中再定义一个循环语句结构,while,do-while,for循环语句都可以进行嵌套,并且可以互相嵌套,下面来看下for循环中嵌套for循环的例子. 如下: publ ...
- js解决IE8不支持html5,css3的问题(respond.js 的使用注意)
IE8.0及以下不支持html5,css3的解析.目前为止IE8以下的版本使用率在10%左右,网站还是有必要兼容的. 1,在你的所有css最后判断引入两个js文件. html5.js 是用来让ie8 ...
- MySQL binlog 日志
一:MySQL 日志的三种类型: statement.row.mix 格式.推荐使用row格式. 怎么设置自己的日志格式呢? 1. set globle binlog_format='MIXED' 2 ...
- 手机PC监听用户复制内容
最近应项目需求,为了获取到更多用户想要搜索的信息,需要把用户点击复制的内容获取到,然后传送给后台以更好的了解客户需求,自己在这个方法上栽了个大跟头,只考虑其一却不知道结合使用,脑袋卡顿,随笔记下,望自 ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- linux下执行java类(运行java定时器)
假如有一个定时器TimerTest.java import java.io.IOException; import java.util.Timer; public class TimerTest { ...
- restful架构风格设计准则(二)以资源为中心,一个url
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 1.REST是一种架构风格,其核心是面向资源,简化设计,降低开发的复杂性 ...
- 解决cors跨域的filter
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; im ...