1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #define MAXN 110
  5 #define MAXM 26
  6 #define MAXL (1<<10)
  7 #define MOD 20090717
  8 using namespace std;
  9 char str[MAXN];
 10 int size, digit[MAXL], dp[30][MAXN][MAXL];
 11 struct node {
 12     int fail, end, next[MAXM];
 13     void Init() {
 14         fail = end = 0;
 15         memset(next, 0, sizeof(next));
 16     }
 17 };
 18 node tree[MAXN];
 19 inline int GET(char ch) {
 20     return ch - 'a';
 21 }
 22 void Insert(char *s, int pos) {
 23     int now, t;
 24     for (now = 0; *s; s++) {
 25         t = GET(*s);
 26         if (!tree[now].next[t]) {
 27             tree[++size].Init();
 28             tree[now].next[t] = size;
 29         }
 30         now = tree[now].next[t];
 31     }
 32     tree[now].end |= (1 << pos);
 33 }
 34 void BFS() {
 35     int now, i, p;
 36     queue<int> q;
 37     q.push(0);
 38     while (!q.empty()) {
 39         now = q.front();
 40         q.pop();
 41         for (i = 0; i < MAXM; i++) {
 42             if (tree[now].next[i]) {
 43                 p = tree[now].next[i];
 44                 q.push(p);
 45                 if (now)
 46                     tree[p].fail = tree[tree[now].fail].next[i];
 47                 tree[p].end |= tree[tree[p].fail].end;
 48             } else
 49                 tree[now].next[i] = tree[tree[now].fail].next[i];
 50         }
 51     }
 52 }
 53 void Init() {
 54     int i, k;
 55     for (i = 0; i < MAXL; i++) {
 56         digit[i] = 0;
 57         for (k = i; k; k >>= 1) {
 58             if (k & 1)
 59                 digit[i]++;
 60         }
 61     }
 62 }
 63 void DoIt(int n, int m, int t) {
 64     int i, j, k, l, p, ans;
 65     for (i = 1; i <= n; i++) {
 66         for (j = 0; j <= size; j++)
 67             memset(dp[i][j], 0, sizeof(int) * (1 << m));
 68     }
 69     dp[0][0][0] = 1;
 70     for (i = 1; i <= n; i++) {
 71         for (j = 0; j <= size; j++) {
 72             for (k = 0; k < (1 << m); k++) {
 73                 if (dp[i - 1][j][k] && (tree[j].end & k) == tree[j].end) {
 74                     for (l = 0; l < MAXM; l++) {
 75                         p = tree[j].next[l];
 76                         dp[i][p][k | tree[p].end] += dp[i - 1][j][k];
 77                         if (dp[i][p][k | tree[p].end] >= MOD)
 78                             dp[i][p][k | tree[p].end] %= MOD;
 79                     }
 80                 }
 81             }
 82         }
 83     }
 84     for (j = ans = 0; j <= size; j++) {
 85         for (k = 0; k < (1 << m); k++) {
 86             if (digit[k] >= t) {
 87                 ans += dp[n][j][k];
 88                 if (ans >= MOD)
 89                     ans %= MOD;
 90             }
 91         }
 92     }
 93     printf("%d\n", ans);
 94 }
 95 int main() {
 96     int n, m, k, i;
 97     Init();
 98     while (scanf("%d%d%d", &n, &m, &k), n) {
 99         tree[0].Init();
100         for (size = i = 0; i < m; i++) {
101             scanf(" %s", str);
102             Insert(str, i);
103         }
104         BFS();
105         DoIt(n, m, k);
106     }
107     return 0;
108 }
posted on 2012-08-04 11:23  DrunBee  阅读(459)  评论(0编辑  收藏  举报