Codeforces Gym 101174 E. Passwords (AC 自动机 + DP)
来源:互联网 发布:linux属于应用软件吗 编辑:程序博客网 时间:2024/05/17 01:12
Problem
给定 N 个单词和整数 A ,B。合法的串 S 为长度在区间 [A, B]
内,仅有大小写字母和数字构成,至少有一个大写字母、一个小写字母和一个数字,且 N 个单词均无法在该串中找到匹配的子串。求 S 串的可行方案数(对结果 MOD 1000003)。
特殊情况:数字 0 1 3 5 7
可分别视作 o i e s t
进行单词串的匹配。同时匹配时忽略大小写。
限制条件
3 ≤ A ≤ B ≤ 20
0 ≤ N ≤ 50
1 ≤ length(Wi) ≤ 20
N 个单词均只有小写字母
解题思路
DP 处理所有合法情况的可行方案数。
- 枚举每种合法的长度 S 。
- 记录是否存在小写字母|大写字母|数字,通过状压记录
- 判断该串的后续状态是否会产生单词串的匹配(使用 AC 自动机处理)。
dp[S][status][idx]
表示长度为 S ,大小写和数字状态为 status ,枚举的第 S 个字符在 AC 自动机中所属节点编号为 idx。
其后续状态有枚举 A-Z
, a-z
, 0-9
。其中 A-Z
由于忽略大小写应视为 a-z
,部分数字应直接处理成对应字母进行处理。
若有 idx 推导的状态加一个字符不会产生单词匹配,则 dp[S][status][idx]
对其后续产生贡献,否则贡献为 0 。
代码
#include<bits/stdc++.h>using namespace std;const int MOD = 1e6 + 3;const int maxn = 1010;const int CH = 128;int A, B, N, dp[22][8][1010];char buf[22];string str = "oi2e4s6t89";struct Trie { int nxt[maxn][CH], fail[maxn], end[maxn]; int root, L; void init() { L = 0; root = newnode(); } int newnode() { for(int i=0;i<CH;i++) nxt[L][i] = -1; end[L++] = 0; return L-1; } void insert(char buf[], int idx) { int p = root; for(int i=0;buf[i];i++) { if(nxt[p][buf[i]] == -1) nxt[p][buf[i]] = newnode(); p = nxt[p][buf[i]]; } end[p] = idx; } void build() { queue<int> que; fail[root] = root; for(int i=1;i<CH;i++) if(nxt[root][i] == -1) nxt[root][i] = root; else fail[nxt[root][i]] = root, que.push(nxt[root][i]); while(!que.empty()) { int p = que.front(); que.pop(); for(int i=0;i<CH;i++) if(nxt[p][i] == -1) nxt[p][i] = nxt[fail[p]][i]; else { fail[nxt[p][i]] = nxt[fail[p]][i]; que.push(nxt[p][i]); } } }} ac;int findAndJugNxt(int nxt, char c) { while(nxt != 0 && ac.nxt[nxt][c] == -1) nxt = ac.fail[nxt]; nxt = ac.nxt[nxt][c]; int tmpNxt = nxt; while(tmpNxt != 0) { if(ac.end[tmpNxt] != 0) return -1; tmpNxt = ac.fail[tmpNxt]; } return nxt;}int main(){ scanf("%d %d %d", &A, &B, &N); ac.init(); for(int i=1;i<=N;i++) { scanf(" %s", buf); ac.insert(buf, i); } ac.build(); dp[0][0][0] = 1; for(int S=0;S<B;S++) for(int status=0;status<8;status++) for(int idx=0, nxt;idx<ac.L;idx++) { if(dp[S][status][idx] == 0) continue; for(char c='a', tc;c<='z';c++) //A-Z for ingore upper or lower { nxt = findAndJugNxt(idx, c); if(nxt != -1) (dp[S+1][status|1][nxt] += dp[S][status][idx]) %= MOD; } for(char c='a';c<='z';c++) { nxt = findAndJugNxt(idx, c); if(nxt != -1) (dp[S+1][status|2][nxt] += dp[S][status][idx]) %= MOD; } for(char c='0', tc;c<='9';c++) { tc = str[c-'0']; nxt = findAndJugNxt(idx, tc); if(nxt != -1) (dp[S+1][status|4][nxt] += dp[S][status][idx]) %= MOD; } } int ans = 0; for(int S=A;S<=B;S++) for(int idx=0;idx<ac.L;idx++) (ans += dp[S][7][idx]) %= MOD; printf("%d\n", ans);}
阅读全文
0 0
- Codeforces Gym 101174 E. Passwords (AC 自动机 + DP)
- CodeForces Gym 100989E Accepted Passwords
- AC自动机+dp(CodeForces
- 【AC自动机】 CodeForces - 163E
- Codeforces Round #248 (Div. 1)C(AC自动机+DP)
- 【codeforces】gym 101137 E - Economy Printing【dp】
- 【codeforces】163E. e-Government AC自动机+树状数组
- bzoj1030(ac自动机+dp)
- hdu2296-(AC自动机+DP)
- HDU2296(AC自动机+DP)
- HYSBZ - 2434 && Codeforces 163 E【AC自动机+dfn序列】
- ac自动机(dp)<AC自动机模板> ---高精度处理
- codeforces GYM 101431E (状态压缩dp+博弈)
- CodeForces Gym 100735E
- Codeforces gym 100685 E
- codeforces [Gym-100814E]
- Codeforces gym 101243 E
- Codeforces 86C Genetic engineering (AC自动机+dp)
- D
- 在筛选试管受精胚胎方面_AI(人工智能)比胚胎学家更靠谱
- appium安装步骤记录
- vue2移动端上传,预览,压缩图片,解决拍照旋转问题
- 一台windows主机安装多个mysql服务
- Codeforces Gym 101174 E. Passwords (AC 自动机 + DP)
- Accept与Content-type区别
- 计算机网络知识总结:
- Codeforces 815B. Karen and Test 【规律】
- Springboot系列:@SpringBootApplication注解
- Android中小数处理(DecimalFormat)
- 用springmvc实现类似restful风格接口(接收和返回为xml格式数据)
- git的使用
- c语言课程设计-学生成绩管理系统