HDU 2825 Wireless Password(AC自动机 + 状压DP)题解
题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个
思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上。
代码:
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100 + 5;
const int M = 50 + 5;
const ull seed = 131;
const double INF = 1e20;
const int MOD = 20090717;
int n, m, K;
int dp[28][maxn][1100];
int num[1100];
struct Aho{
struct state{
int next[26];
int fail, cnt;
}node[maxn];
int size;
queue<int> q; void init(){
size = 0;
newtrie();
while(!q.empty()) q.pop();
} int newtrie(){
memset(node[size].next, 0, sizeof(node[size].next));
node[size].cnt = node[size].fail = 0;
return size++;
} void insert(char *s, int id){
int len = strlen(s);
int now = 0;
for(int i = 0; i < len; i++){
int c = s[i] - 'a';
if(node[now].next[c] == 0){
node[now].next[c] = newtrie();
}
now = node[now].next[c];
}
node[now].cnt = 1 << id;
} void build(){
node[0].fail = -1;
q.push(0); while(!q.empty()){
int u = q.front();
q.pop();
if(node[node[u].fail].cnt && u) node[u].cnt |= node[node[u].fail].cnt;
for(int i = 0; i < 26; i++){
if(!node[u].next[i]){
if(u == 0)
node[u].next[i] = 0;
else
node[u].next[i] = node[node[u].fail].next[i];
}
else{
if(u == 0) node[node[u].next[i]].fail = 0;
else{
int v = node[u].fail;
while(v != -1){
if(node[v].next[i]){
node[node[u].next[i]].fail = node[v].next[i];
break;
}
v = node[v].fail;
}
if(v == -1) node[node[u].next[i]].fail = 0;
}
q.push(node[u].next[i]);
}
}
}
} void query(){
for(int i = 0; i <= n; i++){
for(int j = 0; j < size; j++){
for(int k = 0; k < (1 << m); k++){
dp[i][j][k] = 0;
}
}
}
for(int i = 0; i < 26; i++){
if(node[node[0].next[i]].cnt){
int v = node[node[0].next[i]].cnt;
dp[1][node[0].next[i]][v]++;
// printf("* %d %d %d\n", 1, node[0].next[i], v);
}
else
dp[1][node[0].next[i]][0]++;
}
for(int i = 1; i < n; i++){
for(int j = 0; j < size; j++){
for(int k = 0; k < (1 << m); k++){
if(dp[i][j][k] == 0) continue;
for(int l = 0; l < 26; l++){
if(node[node[j].next[l]].cnt){
int v = node[node[j].next[l]].cnt;
dp[i + 1][node[j].next[l]][k | v] = (dp[i + 1][node[j].next[l]][k | v] + dp[i][j][k]) % MOD;
}
else{
dp[i + 1][node[j].next[l]][k] = (dp[i + 1][node[j].next[l]][k] + dp[i][j][k]) % MOD;
}
}
}
}
}
int ans = 0;
for(int i = 0; i < size; i++){
for(int j = 0; j < (1 << m); j++){
if(num[j] >= K) ans = (ans + dp[n][i][j]) % MOD;
}
}
printf("%d\n", ans);
} }ac;
char s[100];
int main(){
for(int i = 0; i < 1100; i++){
int temp = 0, x = i;
while(x){
temp += x & 1;
x >>= 1;
}
num[i] = temp;
}
while(~scanf("%d%d%d", &n, &m, &K) && n + m + K){
ac.init();
for(int i = 0; i < m; i++){
scanf("%s", s);
ac.insert(s, i);
}
ac.build();
ac.query();
}
return 0;
}
HDU 2825 Wireless Password(AC自动机 + 状压DP)题解的更多相关文章
- hdu2825 Wireless Password(AC自动机+状压dp)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- 【HDU2825】Wireless Password (AC自动机+状压DP)
Wireless Password Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u De ...
- 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 ...
- hdu 4057--Rescue the Rabbit(AC自动机+状压DP)
题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...
- hdu_2825_Wireless Password(AC自动机+状压DP)
题目链接:hdu_2825_Wireless Password 题意: 给你m个串,问长度为n至少含k个串的字符串有多少个 题解: 设dp[i][j][k]表示考虑到长度为i,第j个自动机的节点,含有 ...
- HDU 2825 Wireless Password(AC自动机+DP)
题目链接 做题, #include <cstdio> #include <string> #include <cstring> using namespace st ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
随机推荐
- [Cerc2005]Knights of the Round Table
题目描述 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少有3个骑士参加,且相互憎恨的骑士不能坐在圆桌的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是大于1的奇数,以防 ...
- javascript判断浏览器访问,刷新,返回
话不多说,直接上 if (window.performance.navigation.type === 0/* 正常访问 */) { // 你要干的事 } else if (window.perfor ...
- 07. struts2中对Action的管理方式
web.xml配置文件的常用代码 <filter> <filter-name>struts2</filter-name> <filter-class>o ...
- uniapp根据登录用户的角色动态的改变tabBar的数量和内容
此文章借鉴于https://blog.csdn.net/fuyuumiai/article/details/109746357,在此基础上修改小部分内容,适用于我这种uniapp小白 介绍: 现在我们 ...
- 前端面试之JavaScript中数组的方法!【残缺版!!】
前端面试之JavaScript中数组常用的方法 7 join Array.join()方法将数组中所有元素都转化为字符串并连接在-起,返回最后生成的字 符串.可以指定一个可选的字符串在生成的字符串中来 ...
- (01)-Python3之--字符串操作
1.字符串切片取值 字符串的取值通过索引来读取,从0开始. 取区间值如下:字符串变量名[起始索引:结束索引].包含起始,但不包含结束.例如: str_my = "hello,python!我 ...
- Linux 下安装 JDK
JDK 依赖包: yum install glibc.i686 卸载原有的 JDK 查看本机已安装软件:rpm -qa 查看与java相关的软件:rpm -qa | grep java 删除自带软件: ...
- 使用jiffies的时间比较函数time_after、time_before
1. jiffies简介 首先,操作系统有个系统专用定时器(system timer),俗称滴答定时器,或者系统心跳. 全局变量jiffies取值为自操作系统启动以来的时钟滴答的数目,在头文件< ...
- SpringMVC听课笔记(SpringMVC 表单标签 & 处理静态资源)
1.springmvc表单标签,可以快速开发,表单回显,但是感触不深 2.静态资源的获取,主要是要配置这个
- jvm 总体梳理
jvm 总体梳理 1.类的加载机制 1.1什么是类的加载 1.2类的生命周期 1.3类加载器 1.4类加载机制 2.jvm内存结构 JVM内存模型 2.1jvm内存结构 2.2对象分配规则 3.GC算 ...