题意: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)题解相关推荐

  1. HDU - 2825 Wireless Password(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 m 个匹配串,问长度为 n 的字符串中,至少包含 k 个匹配串(可重叠)的字符串有多少个 题目分析:考虑到n,m,k都特别小,所以可以先用AC自动机将状态关系转移出 ...

  2. HDU - 2825 Wireless Password (AC自动机 + 状压dp)

    题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...

  3. HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)

    题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...

  4. hdu 2825 Wireless Password AC自动机+状态DP

    时间卡得紧,写成递推可以做一些优化 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cs ...

  5. AC自动机+状压dp hdu2825 Wireless Password

    传送门:点击打开链接 题意:有个密码长度为n,现在有m个魔力单词,要求密码中魔力单词的种类数>=k,问这种密码的种类数. 思路:和之前一样,我们会想到AC自动机去压缩状态,把状态给简化.然后我们 ...

  6. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  7. 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|] ,长度 ...

  8. HDU - 3341 Lost's revenge(AC自动机+状压dp)

    题目链接:点击查看 题目大意:给出 n 个模式串,最后给出一个匹配串,问如何重新排列匹配串,可以使得匹配串尽可能多的匹配模式串 题目分析:因为是模式串和匹配串的匹配,所以考虑AC自动机,因为数据范围比 ...

  9. P4045-[JSOI2009]密码【AC自动机,状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4045 题目大意 给nnn个字符串,求有多少个长度为lll的字符串包含所有给出的字符串 解题思路 因为nnn很小, ...

  10. 【hdu2825】ac自动机 + 状压dp

    传送门 题目大意: 给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量. 题解: 因为密码串不多,可以考虑状态压缩 设dp[i][j][sta]表示长为i的字符串匹配到 ...

最新文章

  1. sw如何缩放装配体_SolidWorks关于大型装配体的优化技巧(二)
  2. 魔棒工具--RegionGrow算法简介
  3. Linux下TCP最大连接数受限问题
  4. 5位随机数重复的概率 php_php防止表单重复提交的方法
  5. Windows进程与线程学习笔记(二)—— 线程结构体
  6. 第九届蓝桥杯 Java B组 第三题 复数幂 (详解)
  7. 中countif函数_Count系列函数-Count、Counta、Countblank、Countif、Countifs
  8. MySQL 使用utf8mb4代替utf8
  9. cacti 安装部署
  10. Java中文和拼音相互转换
  11. 计算机课flash课件,flash动画制作获奖课件
  12. 零基础、一次性通过信息系统项目管理师心得与学习计划
  13. 微信公众号API接口调用
  14. win10系统安装+激活+去水印
  15. Android原生模拟器运行ARM APP
  16. pba mode ( path based analysis for sta )
  17. 断臂求生!捷信全线退出医美市场
  18. js 重置表单 reset form
  19. ixgbe 驱动安装
  20. 【机器视觉】移动机器人控制软件的设计与实现

热门文章

  1. Google+再曝漏洞!5250万用户信息恐泄露
  2. [20180423]表空间闪回与snapshot standby
  3. JQuery基础学习笔记(1)
  4. 关于阵列卡的配置参数Cache Policy(缓存策略)
  5. java core 之 异常处理详解
  6. 因为一条SQL,我差点被祭天......
  7. count(1)、count(*) 与 count(列名) 的执行区别
  8. 端午节,我们好好聊聊程序员这个群体
  9. 程序员不满薪资拒绝offer,HR怒称:估计你一辈子就是个程序员
  10. 这几个问题解决了,怎么设计大型网站架构不再是困难