Wireless Password HDU - 2825
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wireless Password HDU - 2825相关的知识,希望对你有一定的参考价值。
Wireless Password
ac自动机 + 状压DP
dp[i][j][k]表示 长度为i在节点j包含串状态为k时的方案数
dp[i][j][k | s] += dp[i-1][u][k] , 其中u是j的父节点, s是走到j节点时新加入的串的状态
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int sigma = 26; 4 const int maxnode = 110; 5 const int mod = 20090717; 6 int dp[26][110][1050]; 7 int n, m, k; 8 int sumbit[1050]; 9 10 struct AC{ 11 int ch[maxnode][sigma]; 12 int f[maxnode], mc[maxnode]; 13 int sz; 14 15 void init(){ 16 memset(mc, 0, sizeof(mc)); 17 memset(ch[0], 0, sizeof(ch[0])); 18 sz = 1; 19 } 20 21 int idx(char c) { 22 return c - ‘a‘; 23 } 24 25 void insert(char *s, int id) { 26 int n = strlen(s), u = 0; 27 for(int i = 0; i < n; i++){ 28 int c = idx(s[i]); 29 if(!ch[u][c]){ 30 memset(ch[sz], 0, sizeof(ch[sz])); 31 ch[u][c] = sz++; 32 } 33 u = ch[u][c]; 34 } 35 mc[u] |= (1<<id); 36 } 37 void getfail(){ 38 queue<int> q; 39 f[0] = 0; 40 for(int c = 0; c < sigma; c++){ 41 int u = ch[0][c]; 42 if(u){ 43 q.push(u); 44 f[u] = 0; 45 } 46 } 47 while(!q.empty()){ 48 int r = q.front(); 49 q.pop(); 50 for(int c = 0; c < sigma; c++){ 51 int u = ch[r][c]; 52 if(!u) { 53 ch[r][c] = ch[f[r]][c]; 54 continue; 55 } 56 q.push(u); 57 int v = f[r]; 58 // while(v && !ch[v][c]) v = f[v]; 59 f[u] = ch[v][c]; 60 mc[u] |= mc[f[u]]; 61 } 62 } 63 } 64 int solve(){ 65 //memset(dp, 0, sizeof(dp)); 66 for(int i = 0; i <= n; i++){ 67 for(int j = 0; j < sz; j++){ 68 for(int sta = 0; sta < (1<<m); sta++){ 69 dp[i][j][sta] = 0; 70 } 71 } 72 } 73 dp[0][0][0] = 1; 74 for(int i = 1; i <= n; i++){ 75 for(int j = 0; j < sz; j++){ 76 for(int sta = 0; sta < (1<<m); sta++){ 77 if(dp[i-1][j][sta] == 0) continue; 78 for(int c = 0; c < sigma; c++){ 79 int v = ch[j][c]; 80 dp[i][v][sta | mc[v]] += dp[i-1][j][sta]; 81 dp[i][v][sta | mc[v]] %= mod; 82 } 83 } 84 } 85 } 86 int ans = 0; 87 for(int i = 0; i < (1<<m); i++){ 88 if(sumbit[i] < k) continue; 89 for(int j = 0; j < sz; j++){ 90 ans = (ans + dp[n][j][i]) % mod; 91 } 92 } 93 return ans; 94 } 95 }; 96 AC ac; 97 int main(){ 98 //freopen("in.txt", "r", stdin); 99 for(int i = 0; i < 1050; i++){ 100 sumbit[i] = 0; 101 for(int j = 0; j < 11; j++){ 102 if(i & (1<<j)) sumbit[i]++; 103 } 104 } 105 while(scanf("%d %d %d", &n, &m, &k) && (n+m+k)){ 106 ac.init(); 107 char s[15]; 108 for(int i = 0; i < m; i++){ 109 scanf("%s", s); 110 ac.insert(s, i); 111 } 112 ac.getfail(); 113 int ans = ac.solve(); 114 printf("%d\n", ans); 115 } 116 return 0; 117 }
以上是关于Wireless Password HDU - 2825的主要内容,如果未能解决你的问题,请参考以下文章
HDU 2825 Wireless Password(AC自动机)
HDU 2825 Wireless Password AC自动机+dp