传送门

题目大意:

给你一些密码片段字符串,让你求长度为n,且至少包含k个不同密码片段串的字符串的数量。

题解:

因为密码串不多,可以考虑状态压缩

设dp[i][j][sta]表示长为i的字符串匹配到j节点且状态为sta的数量。

其中sta存储的是包含的密码串情况,在构建fail指针时,当前节点要并上fail指针所指的节点。

跑ac自动机,儿子节点从父亲节点转移。

最后取dp[len][...][sta]的和,其中sta满足二进制中1的数量>=k,

这一点可以像树状数组的lowbit那样快速求出:

inline int count(int x){int ret = 0;while(x){ret++;x -= (x & -x);}return ret;
}

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 20, L = 20, Mod = 20090717;
int n, m, k, tot;
long long dp[30][110][1100], ans;
char s[20];
queue<int> que;
struct node{int trans[27];int fail, no;int state;inline void clear(){memset(trans, 0, sizeof trans);fail = state = no = 0;}
}trie[1010];
inline int getVal(char st){return st - 'a' + 1;
}
inline void insert(int num){int len = strlen(s + 1), pos = 1;for(int i = 1; i <= len; i++){int val = getVal(s[i]);if(!trie[pos].trans[val])trie[trie[pos].trans[val] = ++tot].clear();pos = trie[pos].trans[val];}trie[pos].state |= 1 << num;
}
inline void buildFail(){for(int i = 1; i <= 26; i++) trie[0].trans[i] = 1;que.push(1);while(!que.empty()){int u = que.front(); que.pop();for(int i = 1; i <= 26; i++){int v = trie[u].fail;while(!trie[v].trans[i]) v = trie[v].fail;int w = trie[u].trans[i];v = trie[v].trans[i];if(w){trie[w].fail = v;que.push(w);trie[w].state |= trie[v].state;}else trie[u].trans[i] = v;}}
}
inline int count(int x){int ret = 0;while(x){ret++;x -= (x & -x);}return ret;
}
inline void solve(){memset(dp, 0, sizeof dp);int limit = 1 << m;dp[0][1][0] = 1;for(int i = 1; i <= n; i++)for(int j = 1; j <= tot; j++)for(int sta = 0; sta < limit; sta++)if(dp[i - 1][j][sta])for(int l = 1; l <= 26; l++){int u = trie[j].trans[l];dp[i][u][sta | trie[u].state] = (dp[i][u][sta | trie[u].state] + dp[i - 1][j][sta]) % Mod;}for(int i = 1; i <= tot; i++)for(int sta = 0; sta < limit; sta++){if(count(sta) >= k)ans = (ans + dp[n][i][sta]) % Mod;}
}
int main(){while(scanf("%d%d%d", &n, &m, &k), n + m + k){trie[tot = 1].clear(); ans = 0;for(int i = 1; i <= m; i++){scanf("%s", s + 1);insert(i - 1);}buildFail();solve();cout << ans << endl;}
}

转载于:https://www.cnblogs.com/CzYoL/p/7450429.html

【hdu2825】ac自动机 + 状压dp相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. ACM-ICPC 2018 南京赛区网络预赛 J AC Challenge (状压dp)

    题意 给你n道题,在你做第ii{i}道题的时候有p[j]p[j]{p[j]}个前置条件,当这些前置条件都满足的时候,我们可以得到a[j]∗t+b[j]a[j]∗t+b[j]a[j] * t + b[j ...

最新文章

  1. hashmap 和 hashcode还是有点关系的
  2. 为什么你那么努力,却很难突破技术瓶颈?
  3. helm search搜索charts命令
  4. LA 3458——Bridge
  5. 华为任职资格_华为采购总部专业任职资格标准|
  6. 【11】 Express安装入门与模版引擎ejs
  7. 解析Excel2007之关键点_Sheet.xml(一)
  8. 说一下syslog日志吧~~~
  9. 图像处理随笔——非极大值抑制
  10. virtualbox启动后一直黑窗_UBUNTU18.04 安装virtualbox-6.0,出现rc=-1908问题解决方法
  11. pandas之combine_first() 合并重叠数据(修补)
  12. python机器学习-糖尿病预测模型
  13. hart协议c语言,简述HART协议命令和语言
  14. MATLAB取整操作
  15. windows环境 java jdbc 连接impala (kerberos认证)
  16. JAVA之假克隆、浅克隆、深克隆
  17. 老兵新传 Visual Basic核心编程及通用模块开发pdf
  18. Caused by: java.net.BindException: Address already in use: bind
  19. 最大回撤python_最大回撤,最大回撤恢复时间与最大回撤持续期
  20. 批量删除asc文件前n行

热门文章

  1. 什么函数是回调函数?
  2. c 语言运算符号大全,c语言运算符号详细说明
  3. law是什么的缩写_Lawyer和Attorney 有什么不同?
  4. sdp ddp内存怎么分_旗舰手机跑分66万+,缩短与PC差距,手机成生产力工具也许不是梦...
  5. linux java 环境配置_linux下java开发环境配置
  6. catalog move.php,catalog.php
  7. 解决win10使用GPU跑程序遇到的一系列报错
  8. Spring Boot 之 itext导出pdf下载
  9. 广西壮族自治区直流充电桩说明书下载_鄂州便携式直流充电桩
  10. mysql数据库(10):数据 备份