博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Wireless Password HDU - 2825
阅读量:5030 次
发布时间:2019-06-12

本文共 2670 字,大约阅读时间需要 8 分钟。

题意:

给出m个模式串,要求构造一长度为n的文本串,至少包括k种模式串,求有多少种可能的模式串。

 

 k<=10  然后可以想到状压

一个文本串,k种模式串,很容易想到AC自动机。

把所有的模式串放入AC自动机上面,然后跑状压DP

跟AC自动机有关的DP一般都要用的AC自动机上的节点。

dp状态定义为dp[ i ][ j ][status]走到长度为i 时,在AC自动机上 j 这个节点 

状态为 status 的方案数。

然后统计答案即可。

由于状态只与上一步有关,所以我滚动了一维,多开一维并不会MLE,也可以写。

 

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 14 #define pi acos(-1.0) 15 #define eps 1e-9 16 #define fi first 17 #define se second 18 #define rtl rt<<1 19 #define rtr rt<<1|1 20 #define bug printf("******\n") 21 #define mem(a, b) memset(a,b,sizeof(a)) 22 #define name2str(x) #x 23 #define fuck(x) cout<<#x" = "<
<
<< id); 80 } 81 82 void build() { 83 queue
Q; 84 fail[root] = root; 85 for (int i = 0; i < 26; i++) 86 if (next[root][i] == -1) next[root][i] = root; 87 else { 88 fail[next[root][i]] = root; 89 Q.push(next[root][i]); 90 } 91 while (!Q.empty()) { 92 int now = Q.front(); 93 Q.pop(); 94 End[now] |=End[fail[now]]; 95 for (int i = 0; i < 26; i++) 96 if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; 97 else { 98 fail[next[now][i]] = next[fail[now]][i]; 99 Q.push(next[now][i]);100 }101 }102 }103 104 void debug() {105 for (int i = 0; i < cnt; i++) {106 printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);107 for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);108 printf("]\n");109 }110 }111 } ac;112 113 114 int main() {115 // FIN;116 while (~sfff(n, m, k)) {117 if (n == 0 && m == 0 && k == 0) break;118 ac.init();119 for (int i = 0; i < m; ++i) {120 scanf("%s", buf);121 ac.insert(buf, i);122 }123 ac.build();124 for (int i = 0; i <2; i++)125 for (int j = 0; j < ac.cnt; j++)126 for (int p = 0; p < (1 << m); p++)127 dp[i][j][p] = 0;128 int now = 0;129 dp[now][0][0] = 1;130 for (int i = 1; i <= n; ++i) {131 now = now ^ 1;132 for (int j = 0; j < ac.cnt; j++)133 for (int p = 0; p < (1 << m); p++)134 dp[now][j][p] = 0;135 for (int j = 0; j < ac.cnt; ++j) {136 for (int status = 0; status < (1 << m); ++status) {137 if (dp[now ^ 1][j][status]) {138 for (int l = 0; l < 26; ++l) {139 int st = (status | ac.End[ac.next[j][l]]);140 dp[now][ac.next[j][l]][st] = (dp[now][ac.next[j][l]][st] + dp[now ^ 1][j][status]) % mod;141 }142 }143 }144 }145 }146 LL ans = 0;147 for (int status = 0; status < (1 << m); ++status) {148 if (cal(status) < k) continue;149 for (int i = 0; i < ac.cnt; ++i)150 ans = (ans + dp[now][i][status]) % mod;151 }152 printf("%lld\n", ans);153 }154 return 0;155 }
View Code

 

转载于:https://www.cnblogs.com/qldabiaoge/p/11379082.html

你可能感兴趣的文章
IOS程序的启动过程
查看>>
连接Linux下 XAMPP集成环境中部署的禅道的数据库MariaDB
查看>>
Java操作Excel和Word
查看>>
Oracle 体系结构之ORACLE物理结构
查看>>
ORA-12538: TNS: no such protocol adapter
查看>>
盒子模型
查看>>
局域网协议
查看>>
[HNOI2012]永无乡 线段树合并
查看>>
Spring整合hibernate:3、使用XML进行声明式的事务管理
查看>>
SqlServer之Convert 函数应用格式化日期(转)
查看>>
软件测试领域中的10个生存和发展技巧
查看>>
Camera前后摄像头同时预览
查看>>
HDU 1856
查看>>
课堂作业01--架构师的职责
查看>>
iOS计算富文本(NSMutableAttributedString)高度
查看>>
2017/09/15 ( 框架2)
查看>>
Centos下源码安装git
查看>>
gulp-rev-append md5版本号
查看>>
IO流之File类
查看>>
sql 基础语句
查看>>