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 }
  • 相关阅读:
    SentiAnalysis
    大数据索引技术 B+ tree vs LSM tree
    Regression, 回归问题
    Data Mining with R
    Why Vector Clock are Easy or Hard?
    How to know what an HRESULT code means?
    如何判断数据库表的某个列上有重复值的记录存在?
    关于SharePoint 2010里Servers in farm页面里status意义的澄清
    SharePoint Security系列 之二 CrossSite Request Forgery
    从MOSS2007升级到SharePoint2010后Report Server content types升级失败
  • 原文地址:https://www.cnblogs.com/yyf0309/p/8640870.html
Copyright © 2011-2022 走看看