标签:
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int MAXN = 107; const int MaxSon = 26; const int Mod = 20090717; const int oo = 1e9+7; struct Ac_Trie { int next[MAXN][MaxSon]; int Fail[MAXN], End[MAXN]; int cnt, root; int newnode() { for(int i=0; i<MaxSon; i++) next[cnt][i] = -1; Fail[cnt] = End[cnt] = false; return cnt++; } void InIt() { cnt = 0; root = newnode(); } void Insert(char s[], int t) { int now = root; for(int i=0; s[i]; i++) { int k = s[i]-‘a‘; if(next[now][k] == -1) next[now][k] = newnode(); now = next[now][k]; } End[now] = 1<<t; } void GetFial() { queue<int>Q; int now = root; for(int i=0; i<MaxSon; i++) { if(next[now][i] == -1) next[now][i] = root; else { Fail[next[now][i]] = root; Q.push(next[now][i]); } } while(Q.size()) { now = Q.front(); Q.pop(); for(int i=0; i<MaxSon; i++) { if(next[now][i] == -1) next[now][i] = next[Fail[now]][i]; else { Fail[next[now][i]] = next[Fail[now]][i]; Q.push(next[now][i]); } } End[now] |= End[Fail[now]]; } } }; Ac_Trie ac; int Find(int i) { int k=0; while(i) { if(i % 2) k++; i /= 2; } return k; } int main() { int N, M, K; int sum[1024] ={0}; for(int i=0; i<1024; i++) sum[i] = Find(i); while(scanf("%d%d%d", &N, &M, &K), N+M+K) { char s[MAXN]; ac.InIt(); for(int i=0; i<M; i++) { scanf("%s", s); ac.Insert(s, i); } ac.GetFial(); int dp[2][MAXN][1024] = {0}, op=0, Len = 1<<M; dp[1][0][0] = 1; while(N--) { memset(dp[op], 0, sizeof(dp[op])); for(int i=0; i<ac.cnt; i++) for(int k=0; k<Len; k++) {///把k放中间优化一下...否则超时 if(dp[op^1][i][k] == 0) continue; for(int j=0; j<MaxSon; j++) { (dp[op][ac.next[i][j]][k|ac.End[i]] += dp[op^1][i][k])%=Mod; } } op ^= 1; } int ans = 0; for(int i=0; i<ac.cnt; i++) for(int j=0; j<Len; j++) { if(sum[j] >= K || sum[ac.End[i]|j] >= K) { ans += dp[op^1][i][j]; ans %= Mod; } } printf("%d\n", ans); } return 0; }
Wireless Password - HDU 2825(ac自动机+状态压缩)
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4758136.html