Wireless Password HDU - 2825

Posted yijiull

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wireless Password HDU - 2825相关的知识,希望对你有一定的参考价值。

Wireless Password

 HDU - 2825 

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 }
View Code

 

以上是关于Wireless Password HDU - 2825的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2825 Wireless Password

HDU 2825 Wireless Password(AC自动机)

[HDU2825]Wireless Password

HDU 2825 Wireless Password AC自动机+dp

HDU 2825 Wireless Password ( Trie图 && 状态压缩DP )

HDU2825Wireless PasswordAC自动机,状态压缩DP