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 ...
随机推荐
- Redis 实战 —— 04. Redis 数据结构常用命令简介
字符串 P39 Redis 的字符串是一个有字节组成的序列,可以存储以下 3 种类型的值:字节串(byte string).整数.浮点数. 在需要的时候, Redis 会将整数转换成浮点数.整数的取值 ...
- Redis 实战 —— 05. Redis 其他命令简介
发布与订阅 P52 Redis 实现了发布与订阅(publish/subscribe)模式,又称 pub/sub 模式(与设计模式中的观察者模式类似).订阅者负责订阅频道,发送者负责向频道发送二进制字 ...
- click的简单使用
click的简单使用 先通过一个简单的例子来认知一下click把 import click @click.command() @click.option('-p', '--port', default ...
- 配接Cisco设备
- MySQL进阶:约束,多表设计,多表查询,视图,数据库备份与还原
MySQL进阶 知识点梳理 一.约束 1. 外键约束 为什么要有外键约束 例如:一个user表,一个orderlist 如果现在想要直接删除id为1的张三,但是orderlist里还有用户id为1的订 ...
- 向HDFS中指定的文件追加内容,由用户指定内容追加到原有文件的开头或结尾。
1 import java.io.FileInputStream; 2 import java.io.IOException; 3 import java.text.SimpleDateFormat; ...
- SICP 解题集 — SICP 解题集 https://sicp.readthedocs.io/en/latest/
SICP 解题集 - SICP 解题集 https://sicp.readthedocs.io/en/latest/
- 使用Redis有序集合实现投票排行榜系统
https://mp.weixin.qq.com/s/GcPF8jte8Nzi4Ae0jojXuQ 先说最简单的排行榜.其实之前我们有个用于投票的系统,但是他没有用有序集合,他是这样做的:用redis ...
- 判断2个list中是否有相同的数据(相交)Collections.disjoint
https://blog.csdn.net/yang_niuxxx/article/details/85092490 private void initData() { for (int i = 0; ...
- 算法总结篇---AC自动机
目录 写在前面 算法流程 引例: 概述: Trie树的构建(第一步) 失配指针(第二步) 构建失配指针 字典树和字典图 多模式匹配 例题 写在前面 鸣谢: OiWiki 「笔记」AC 自动机---Lu ...