标签:
转自: http://www.cnblogs.com/ltang/archive/2010/11/25/1887573.html
解题思路:
建立trie图,我们可以假设起点均为root节点,题目转化为求解root经过m步到达所有节点的总和
dp求解,如果存在i->j的路径,counter[m, j] += counter[m-1, i];初始条件为counter[0, root] = 1;
显然,还需要使用高精度
1 代码 2 3 #include <iostream> 4 #include <map> 5 using namespace std; 6 7 const int MAXP = 10; 8 const int MAXL = 10; 9 const int MAXN = 50; 10 const int MAXNODS = MAXP * MAXL + 1; 11 const int base = 1e9; 12 13 int size, n, a, b; 14 int trie[MAXNODS][MAXN]; 15 int queue[MAXNODS], suffix[MAXNODS]; 16 bool danger[MAXNODS], visited[MAXNODS]; 17 char letter[MAXP + 1]; 18 int counter[2][MAXNODS][21], ans[21]; 19 20 map<char, int>dic; 21 22 void Build_Trie() 23 { 24 int t, len, p = 0; 25 len = strlen(letter); 26 for (int i = 0; i < len; i++) 27 { 28 t = dic[letter[i]]; 29 if (trie[p][t] == 0) trie[p][t] = ++size; 30 p = trie[p][t]; 31 if (danger[p]) break; 32 } 33 danger[p] = true; 34 } 35 36 void Build_Graph() 37 { 38 int head = 1, tail = 0; 39 queue[0] = 0; 40 for(int i = 0; i < n; i++) 41 if (trie[0][i]) queue[++tail] = trie[0][i]; // 根节点所有子节点的后缀结点均为根节点 42 while (head <= tail) 43 { 44 danger[queue[head]] |= danger[suffix[queue[head]]]; //后缀结点为危险节点,该节点也为危险节点 45 if (!danger[queue[head]]) 46 { 47 for(int i = 0; i < n; i++) 48 { 49 if (trie[queue[head]][i] == 0) 50 trie[queue[head]][i] = trie[suffix[queue[head]]][i];//如果不存在i孩子,则指向后缀结点的i孩子 51 else 52 { 53 queue[++tail] = trie[queue[head]][i]; 54 suffix[queue[tail]] = trie[suffix[queue[head]]][i];//计算后缀结点 55 } 56 } 57 } 58 ++head; 59 } 60 } 61 62 void add(int *p, int * q) 63 { 64 if (p[0] < q[0]) p[0] = q[0]; 65 for (int k = 1; k <= p[0]; k++) 66 { 67 p[k] += q[k]; 68 p[k + 1] += (p[k] / base); 69 p[k] %= base; 70 } 71 if (p[p[0] + 1])p[0]++; 72 } 73 74 void bfs(int node) 75 { 76 if (visited[node])return; 77 visited[node] = true; 78 for (int i = 0; i < n; i++) 79 { 80 if (!danger[trie[node][i]]) 81 { 82 add(counter[a][trie[node][i]], counter[b][node]); 83 bfs(trie[node][i]); 84 } 85 } 86 } 87 88 void bfs_ans(int node) 89 { 90 if (visited[node]) return; 91 visited[node] = true; 92 add(ans, counter[a][node]); 93 for (int i = 0; i < n; i++) 94 if (!danger[trie[node][i]]) bfs_ans(trie[node][i]); 95 } 96 97 int main() 98 { 99 int p, m, ch, i; 100 101 memset(danger, 0, sizeof(danger)); 102 memset(trie, 0, sizeof(trie)); 103 104 scanf("%d %d %d\n", &n, &m, &p); 105 for (i = 0; i < n; i++)scanf("%c", &ch), dic[ch] = i; 106 for (i = 0; i < p; i++)scanf("%s", letter), Build_Trie(); 107 Build_Graph(); 108 109 a = 1, b = 0; 110 counter[1][0][0] = counter[1][0][1] = 1; 111 for (i = 0; i < m; i++) 112 { 113 swap(a, b); 114 memset(visited, 0, sizeof(visited)); 115 memset(counter[a], 0, sizeof(counter[a])); 116 bfs(0); 117 } 118 memset(visited, 0, sizeof(visited)); 119 memset(ans, 0, sizeof(ans)); 120 bfs_ans(0); 121 printf("%d", ans[ans[0]]); 122 for (i = ans[0] - 1; i > 0; i--) 123 printf("%.9d", ans[i]); 124 printf("\n"); 125 return 0; 126 }
标签:
原文地址:http://www.cnblogs.com/david-wang/p/4344111.html