zoukankan      html  css  js  c++  java
  • Remember the Word

    uvalive3942:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1943

    题意:给以一个串,然后给你一些单词,问你这个串由这些单词组成的话,可以有多少种组成方式。

    题解:这是白书上的一道题目。开始,觉得是DP,但是不知道怎么搞。看了白书上的解释,慢慢的才弄了出来。用dp【i】表示从i到strlen(s)-1最多的组成方式,即以字符i开头。这样的话,就很明显了,dp【i】=sum(dp[i+len(x)])(x是i.....len-1的前缀),那么只要查询i....len-1之间的前缀,如果找到一个前缀,就更新。通过这一题,有了更深的体会,Trie树的另外一个名字,前缀树。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define maxn 1100000
     6 using namespace std;
     7 int dp[300002];
     8 char str[300002];
     9 int current;
    10 struct Nod {        //0为无效值
    11     int lnk[26], val;
    12     char ss[28];
    13     void init() {
    14         memset(lnk, 0, sizeof(lnk));
    15         memset(ss, 0, sizeof(ss));
    16         val = 0;
    17     }
    18 };
    19 const char BASE = 'a';
    20 struct Trie {
    21     Nod buf[maxn];
    22     int len;
    23     void init() {
    24         buf[len=0].init();
    25     }
    26     void insert(char * str) {
    27         int now = 0;
    28         for(int i = 0; str[i]; i ++) {
    29             int & nxt = buf[now].lnk[str[i]-BASE];
    30             if(!nxt)buf[nxt=++len].init();
    31              now = nxt;
    32         }
    33          buf[now].val=1;
    34     }
    35     void  search(char * str) {
    36         int now = 0;
    37         for(int i = 0; str[i]; i ++) {
    38             int & nxt = buf[now].lnk[str[i]-BASE];
    39             now = nxt;
    40             if(!nxt)return;//注意这里的返回,不然会tle
    41             if(buf[now].val==1){
    42                 dp[current]=(dp[current]+dp[current+i+1])%20071027;
    43             }
    44         }
    45     }
    46 } trie;
    47 int n;
    48 char ss[103];
    49 char s1[300002];
    50  int main(){
    51      int tt=1;
    52      while(~scanf("%s",str)){
    53      trie.init();
    54      scanf("%d",&n);
    55      memset(dp,0,sizeof(dp));
    56      while(n--){
    57         scanf("%s",ss);
    58         trie.insert(ss);
    59      }
    60       int len=strlen(str);
    61           dp[len]=1;
    62       for(int i=len-1;i>=0;i--){
    63            current=i;
    64           trie.search(str+i);
    65       }
    66       printf("Case %d: %d
    ",tt++,dp[0]);
    67   }
    68 }
    View Code
  • 相关阅读:
    C语言修炼-第2天
    static_cast, dynamic_cast, reinterpret_cast, const_cast的区别
    构造函数不能为虚函数的原因
    matlab2016b ubuntu命令行安装 + matconvnet的安装
    python debug open_files
    构造函数不能被继承的原因
    NNVM代码阅读
    ncnn阅读
    Deep TEN: Texture Encoding Network
    git命令笔记
  • 原文地址:https://www.cnblogs.com/chujian123/p/3844207.html
Copyright © 2011-2022 走看看