zoukankan      html  css  js  c++  java
  • UVa Live 3942 Remember the Word

    题目传送门

      高速路出口I

      高速路出口II

    题目大意

      给定若干种短串,和文本串$S$,问有多少种方式可以将短串拼成长串。

      显然,你需要一个动态规划。

      用$f[i]$表示拼出串$S$前$i$个字符的方案数。

      转移是显然的。枚举上一个拼接的串的长度,然后判断它是否存在,如果存在就把$f[i]$加上$f[i - l]$。

      这个判断存在可以用Hash。当然可以对每个短串的反串建立Trie树,然后在Trie树上查一查$i$往前会走到长度为哪些的终止状态。

      由于我懒,不想写Trie树,直接用平板电视的hash表,然后慢得起飞。

    Code

     1 /**
     2  * UVa Live
     3  * Problem#3942
     4  * Accepted
     5  * Time: 603ms
     6  */
     7 #include <ext/pb_ds/assoc_container.hpp>
     8 #include <ext/pb_ds/hash_policy.hpp>
     9 #include <iostream>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <cstdio>
    13 using namespace std;
    14 using namespace __gnu_pbds;
    15 typedef bool boolean;
    16 
    17 #define ui unsigned int
    18 
    19 const int N = 3e5 + 5, M = 20071027, L = 101;
    20 const ui base = 200379;
    21 
    22 int n;
    23 char S[N], buf[L];
    24 ui ha[N], ps[N];
    25 cc_hash_table<int, boolean> mp[L];
    26 
    27 inline void prepare() {
    28     ps[0] = 1;
    29     for (int i = 1; i < N; i++)
    30         ps[i] = ps[i - 1] * base;
    31 }
    32 
    33 inline boolean init() {
    34     if (scanf("%s", S + 1) == EOF)    return false;
    35     scanf("%d", &n);
    36     for (int i = 1; i < L; i++)
    37         mp[i].clear();
    38     int l;
    39     ui s;
    40     for (int i = 1; i <= n; i++) {
    41         scanf("%s", buf);
    42         for (l = 0, s = 0; buf[l]; l++)
    43            s = (s * base) + buf[l];
    44         mp[l][s] = true;    
    45     }
    46     return true;
    47 }
    48 
    49 int f[N];
    50 inline void solve() {
    51     f[0] = 1, ha[0] = 0;
    52     n = strlen(S + 1);
    53     for (int i = 1; i <= n; i++)
    54         ha[i] = ha[i - 1] * base + S[i];
    55     for (int i = 1; i <= n; i++) {
    56         f[i] = 0;
    57         for (int j = 1; j < L && j <= i; j++) {
    58             ui s = ha[i] - ha[i - j] * ps[j];
    59             if (mp[j].find(s) != mp[j].end())
    60                 f[i] = (f[i] + f[i - j]) % M;
    61         }
    62     }
    63     printf("%d
    ", f[n]);
    64 }
    65 
    66 int kase = 0;
    67 int main() {
    68     prepare();
    69     while(init()) {
    70         printf("Case %d: ", ++kase);
    71         solve();
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    asp.net的尖括号绑定字段总结
    在 ASP.NET 中实现不同角色的用户使用不同登录界面的方法
    同一个页面内根据分类查询
    利用修改AccessDataSource的sql语句来检索数据
    ADO.NET站内模糊搜索
    又是一个新阶段
    完成一个测试的小功能实践题
    苦心志,劳筋骨,饿体肤,乏其身,乱其所为
    毕业设计进入收尾阶段
    两种模糊过滤关键字的方法
  • 原文地址:https://www.cnblogs.com/yyf0309/p/8640870.html
Copyright © 2011-2022 走看看