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 ...
随机推荐
- Python语言程序设计---函数的定义与使用
推荐一个Python学习交流的q群:610380249 在学习Python的过程中,有什么不懂的问题都可以发群里,一起讨论. 1 函数的理解和定义 函数是一段代码的表示,所指定的参数是一种占位符,如果 ...
- linux 文件目录权限
文件目录权限: 什么是文件权限: 在Linux中,每个文件都有所属的所有者,和所有组,并且规定了文件的所有者,所有组以及其他人对文件的,可读,可写,可执行等权限. 对于目录的权限来说,可读是读取目录文 ...
- ajax异步实现文件分片上传
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 不错的网站压力测试工具webbench
webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统:Linux 2.前期准备:yum install ...
- LR_添加系统资源监控失败
1.服务开启情况:RPC.Rmote Resgistry.Network DDE.Server.Workstation.Network connection以上服务是否已开启 2.是否开了防火墙,如有 ...
- jQuery 点击当前展开其他隐藏
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- Xamarin.Forms: 无限滚动的ListView(懒加载方式)
说明 在本博客中,学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView.这个无限滚动函数在默认的Xamarin.Forms不存在,因此我们需要为此添加插件.在这里我 ...
- PIGS_POJ1149
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20253 Accepted: 9252 Description ...
- js异步、事件循环(EventLoop)小结
单线程 众所周知,JS是单线程的语言,之所以是单线程,用一句烂大街的话就是,如果两个线程同时操作一个DOM节点,那么该以哪个为准呢,虽然多线程也有办法解决,但是js毕竟是浏览器脚本语言,不需要那么复杂 ...
- Vue3.0短视频+直播|vue3+vite2+vant3仿抖音界面|vue3.x小视频实例
基于vue3.0构建移动端仿抖音/快手短视频+直播实战项目Vue3-DouYin. 5G时代已来,短视频也越来越成为新一代年轻人的娱乐方式,在这个特殊之年,又将再一次成为新年俗! 基于vue3.x+v ...