bzoj 1212: [HNOI2004]L语言

思路:字典树+dp, dp[ i ] 表示 前缀到 i 能不能被理解, 如果dp[ i ] 是能被理解的那么, 把i + 1, i + 2 ....  在字典树上走,走到一个单词就转移。

,这样可行的原因是因为模板串长度不超过10,所以字典树的深度不会超过10, 所以进行一次dp的复杂度为 10 * n;

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define ll long long
 4 #define fi first
 5 #define se second
 6 #define mk make_pair
 7 #define pii pair<int,int>
 8 #define piii pair<int, pair<int,int> >
 9 
10 using namespace std;
11 
12 const int N = 1e6 + 7;
13 const int inf = 0x3f3f3f3f;
14 const LL INF = 0x3f3f3f3f3f3f3f3f;
15 const int mod = 1e9 + 7;
16 const int Mod = 2009;
17 
18 int ch[500][26], tot, n, m;
19 bool is[500], dp[N];
20 char s[N];
21 int getNode() {
22     ++tot;
23     memset(ch[tot], 0, sizeof(ch[tot]));
24     is[tot] = false;
25     return tot;
26 }
27 
28 void add(const char *s, int n) {
29     int u = 0;
30     for(int i = 0; i < n; i++) {
31         if(!ch[u][s[i] - 'a']) {
32             ch[u][s[i] - 'a'] = getNode();
33         }
34         u = ch[u][s[i] - 'a'];
35     }
36     is[u] = true;
37 }
38 
39 
40 int main() {
41     scanf("%d%d", &n, &m);
42     for(int i = 1; i <= n; i++) {
43         scanf("%s", s);
44         add(s, strlen(s));
45     }
46 
47     while(m--) {
48         memset(dp, false, sizeof(dp));
49         scanf("%s", s + 1);
50         n = strlen(s + 1);
51         dp[0] = true;
52         for(int i = 0; i < n; i++) {
53             if(dp[i]) {
54                 int j = i + 1, u = 0;
55                 while(j <= n && ch[u][s[j] - 'a']) {
56                     u = ch[u][s[j] - 'a'];
57                     if(is[u]) dp[j] = true;
58                     j++;
59                 }
60             }
61         }
62 
63         int ans = 0;
64         for(int i = 1; i <= n; i++)
65             if(dp[i]) ans = i;
66         printf("%d\n", ans);
67     }
68     return 0;
69 }
70 
71 
72 /*
73 */

 

posted @ 2018-05-25 17:12  NotNight  阅读(101)  评论(0编辑  收藏  举报