zoukankan      html  css  js  c++  java
  • LA 3942 背单词

    https://vjudge.net/problem/UVALive-3942

    题意:

    给出一个由S个不同单词组成的字典和一个长字符串。把这个字符串分解成若干个单词的连接,有多少种方法?比如,有4个单词a、b、cd、ab,则abcd有两种分解方法:a+b+cd和ab+cd。

    思路:

    建立字典树,查询的时候令d(i)表示从字符i开始的字符串的分解方案数,则d(i)=sum{d(i+len(x))|单词x是S[i..L]的前缀}。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<string>
     4 #include<cstring>
     5 using namespace std;
     6 
     7 const int maxnode = 4000 * 100 + 10;
     8 const int sigma_size = 26;
     9 const int maxn = 300000 + 10;
    10 char str[maxn],s[100+5];
    11 int n, dp[maxn];
    12 
    13 
    14 struct Trie
    15 {
    16     int ch[maxnode][sigma_size];
    17     int val[maxnode];
    18     int sz;
    19 
    20     void init()
    21     {
    22         sz = 1;
    23         memset(ch[0], 0, sizeof(ch[0]));
    24     }
    25 
    26     void insert(char *s, int v)
    27     {
    28         int u = 0, len = strlen(s);
    29         for (int i = 0; i < len; i++)
    30         {
    31             int c = s[i] - 'a';
    32             if (!ch[u][c])
    33             {
    34                 memset(ch[sz], 0, sizeof(ch[sz]));
    35                 val[sz] = 0;
    36                 ch[u][c] = sz++;
    37             }
    38             u = ch[u][c];
    39         }
    40         val[u] = v;
    41     }
    42 
    43     int find(char *s, int pos)
    44     {
    45         int len = strlen(s), u = 0, ans = 0;
    46         for (int i = pos; i < len; i++)
    47         {
    48             int c = s[i] - 'a';
    49             if (ch[u][c] == 0)  break;
    50             u = ch[u][c];
    51             if (val[u] == 1)
    52                 ans = (ans + dp[i + 1]) % 20071027;
    53         }
    54         return ans;
    55     }
    56 }T;
    57 
    58 
    59 int main()
    60 {
    61     //freopen("D:\txt.txt", "r", stdin);
    62     int kase = 0;
    63     while (~scanf("%s", str))
    64     {
    65         scanf("%d", &n);
    66         T.init();
    67         for (int i = 0; i < n; i++)
    68         {
    69             scanf("%s", s);
    70             T.insert(s, 1);
    71         }
    72         int len = strlen(str);
    73         dp[len] = 1;
    74         for (int i = len - 1; i >= 0; i--)
    75             dp[i] = T.find(str, i);
    76         printf("Case %d: %d
    ", ++kase, dp[0]);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    pytest_04
    pytest_03
    pytest_02
    CF 1416C XOR Trie
    CF 1413D
    ZOJ 3725 概率dp
    ZOJ 3726
    位运算
    CF1439C 线段树
    unordered_set
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6597936.html
Copyright © 2011-2022 走看看