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;elsenode[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); }elsedp[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; }
转载于:https://www.cnblogs.com/KirinSB/p/11187858.html
HDU 2825 Wireless Password(AC自动机 + 状压DP)题解相关推荐
- HDU - 2825 Wireless Password(AC自动机+状压dp)
题目链接:点击查看 题目大意:给出 m 个匹配串,问长度为 n 的字符串中,至少包含 k 个匹配串(可重叠)的字符串有多少个 题目分析:考虑到n,m,k都特别小,所以可以先用AC自动机将状态关系转移出 ...
- HDU - 2825 Wireless Password (AC自动机 + 状压dp)
题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...
- HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)
题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...
- hdu 2825 Wireless Password AC自动机+状态DP
时间卡得紧,写成递推可以做一些优化 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cs ...
- AC自动机+状压dp hdu2825 Wireless Password
传送门:点击打开链接 题意:有个密码长度为n,现在有m个魔力单词,要求密码中魔力单词的种类数>=k,问这种密码的种类数. 思路:和之前一样,我们会想到AC自动机去压缩状态,把状态给简化.然后我们 ...
- 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 6086 Rikka with String(AC自动机+状压dp)
题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...
- HDU - 3341 Lost's revenge(AC自动机+状压dp)
题目链接:点击查看 题目大意:给出 n 个模式串,最后给出一个匹配串,问如何重新排列匹配串,可以使得匹配串尽可能多的匹配模式串 题目分析:因为是模式串和匹配串的匹配,所以考虑AC自动机,因为数据范围比 ...
- P4045-[JSOI2009]密码【AC自动机,状压dp】
正题 题目链接:https://www.luogu.com.cn/problem/P4045 题目大意 给nnn个字符串,求有多少个长度为lll的字符串包含所有给出的字符串 解题思路 因为nnn很小, ...
- 【hdu2825】ac自动机 + 状压dp
传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...
最新文章
- sw如何缩放装配体_SolidWorks关于大型装配体的优化技巧(二)
- 魔棒工具--RegionGrow算法简介
- Linux下TCP最大连接数受限问题
- 5位随机数重复的概率 php_php防止表单重复提交的方法
- Windows进程与线程学习笔记(二)—— 线程结构体
- 第九届蓝桥杯 Java B组 第三题 复数幂 (详解)
- 中countif函数_Count系列函数-Count、Counta、Countblank、Countif、Countifs
- MySQL 使用utf8mb4代替utf8
- cacti 安装部署
- Java中文和拼音相互转换
- 计算机课flash课件,flash动画制作获奖课件
- 零基础、一次性通过信息系统项目管理师心得与学习计划
- 微信公众号API接口调用
- win10系统安装+激活+去水印
- Android原生模拟器运行ARM APP
- pba mode ( path based analysis for sta )
- 断臂求生!捷信全线退出医美市场
- js 重置表单 reset form
- ixgbe 驱动安装
- 【机器视觉】移动机器人控制软件的设计与实现
热门文章
- Google+再曝漏洞!5250万用户信息恐泄露
- [20180423]表空间闪回与snapshot standby
- JQuery基础学习笔记(1)
- 关于阵列卡的配置参数Cache Policy(缓存策略)
- java core 之 异常处理详解
- 因为一条SQL,我差点被祭天......
- count(1)、count(*) 与 count(列名) 的执行区别
- 端午节,我们好好聊聊程序员这个群体
- 程序员不满薪资拒绝offer,HR怒称:估计你一辈子就是个程序员
- 这几个问题解决了,怎么设计大型网站架构不再是困难