zoukankan      html  css  js  c++  java
  • UVa 1401 (Tire树) Remember the Word

    d(i)表示从i开始的后缀即S[i, L-1]的分解方法数,字符串为S[0, L-1]

    则有d(i) = sum{ d(i+len(x)) | 单词x是S[i, L-1]的前缀 }

    递推边界为d(L) = 1,代表空串。

    将前n个单词构造一颗Tire树,在树中查找后缀的过程中遇到一个单词节点就代表找到一个状态转移中的x

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int maxnode = 400000 + 10;
     5 const int maxl = 100 + 10;
     6 const int sigma_size = 26;
     7 const int MOD = 20071027;
     8 
     9 char s[maxnode];
    10 int l;
    11 int d[maxnode];
    12 char s1[maxl];
    13 
    14 int sz;
    15 int ch[maxnode][sigma_size];
    16 int val[maxnode];
    17 
    18 inline int idx(char c) { return c - 'a'; }
    19 
    20 void Init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }
    21 
    22 void insert(char* s, int v)
    23 {
    24     int n = strlen(s), u = 0;
    25     for(int i = 0; i < n; i++)
    26     {
    27         int c = idx(s[i]);
    28         if(!ch[u][c])
    29         {
    30             memset(ch[sz], 0, sizeof(ch[sz]));
    31             val[sz] = 0;
    32             ch[u][c] = sz++;
    33         }
    34         u = ch[u][c];
    35     }
    36     val[u] = v;
    37 }
    38 
    39 void solve()
    40 {
    41     for(int i = l-1; i >= 0; i--)
    42     {
    43         int u = 0;
    44         for(int j = i; j < l; j++)
    45         {
    46             int c = idx(s[j]);
    47             if(!ch[u][c]) break;
    48             u = ch[u][c];
    49             if(val[u]) d[i] = (d[i] + d[j + 1]) % MOD;
    50         }
    51     }
    52 }
    53 
    54 int n;
    55 int main()
    56 {
    57     //freopen("in.txt", "r", stdin);
    58 
    59     int kase = 0;
    60     while(scanf("%s", s) == 1)
    61     {
    62         Init();
    63         l = strlen(s);
    64         scanf("%d", &n);
    65         while(n--) { scanf("%s", s1); insert(s1, 1); }//val[i] = 1表示这是一个单词节点
    66         memset(d, 0, sizeof(d));
    67         d[l] = 1;
    68         solve();
    69         printf("Case %d: %d
    ", ++kase, d[0] % MOD);
    70     }
    71 
    72     return 0;
    73 }
    代码君
  • 相关阅读:
    Spring学习笔记(二)----Spring IOC
    LeetCode----正则表达式匹配「动态规划」
    Markdown----一款轻量级标记语言
    LeetCode----最长回文子串「动态规划」
    数据结构(六)
    数据结构(五)
    HDOJ3613解题报告【拓展KMP】
    HDOJ1358解题报告【KMP算法next数组的使用】
    POJ1990解题报告【树状数组】
    HDOJ1507解题报告【二分图染色】
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4385744.html
Copyright © 2011-2022 走看看