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

    Trie+DP


    特里白书上的题训练。

    它说,意大利是一个字符串,可以有多种组成的小弦。

    例如

    abcd 

    4

    a

    b

    cd

    ab

    abcd=a+b+cd。abcd=ab+cd;


    递推为:从最后一位往前。dp[i]=dp[i]+dp[i+ len[x]]  x为输入时的顺序,附加到节点中。是 i~strlen(S)的前缀。S[1,2,3,…,i,…len]

    构建Trie树时,把顺序也附加到节点中。


    最后search的时候 找出为多少个字符串的前缀,并把这些前缀都加起来。



    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<stack>
    #include<iostream>
    #include<list>
    #include<set>
    #include<cmath>
    #define INF 0x7fffffff
    #define eps 1e-6
    #define LL long long
    using namespace std;
    const int MOD=20071027;
    
    struct Trie
    {
        int word[4001*100][26];
        int ex[4001*100];
        int size;
    
        void clear()
        {
            memset(word[0],0,sizeof(word[0]));
            size=1;
            ex[0]=0;
        }
    
        int insert(char *s,int v)
        {
            int u=0,c;
            for(int i=0; s[i]!=''; i++)
            {
                int c=s[i]-'a';
                if(!word[u][c])
                {
                    memset(word[size],0,sizeof(word[size]));
                    ex[size]=0;
                    word[u][c]=size++;
                }
                u=word[u][c];
            }
            ex[u]=v;
        }
    
        int search(char *s,int len,vector<int>& ans)
        {
            int u=0,c;
            for(int i=0; s[i]!=''&&i<len; i++)
            {
                c=s[i]-'a';
                if(!word[u][c])return 0;
                u=word[u][c];
                if(ex[u])
                    ans.push_back(ex[u]);
            }
        }
    } wo;
    
    char str[300001];
    int dp[300001];
    int n;
    int le[4001];
    
    int main()
    {
        int nn=1;
        while(scanf("%s",str)!=EOF)
        {
            scanf("%d",&n);
            wo.clear();
            memset(dp,0,sizeof(dp));
            char tmp[101];
            int len=strlen(str);
    
            for(int i=0; i<n; i++)
            {
                scanf("%s",tmp);
                le[i+1]=strlen(tmp);
                wo.insert(tmp,i+1);
            }
            dp[len]=1;
            for(int i=len-1; i>=0; i--)
            {
                vector<int>ans;
                wo.search(str+i,len-i,ans);
                for(int j=0; j<ans.size(); j++)
                    dp[i]=(dp[i]+dp[i+le[ans[j]]])%MOD;
            }
            printf("Case %d: %d
    ",nn++,dp[0]);
        }
    }
    


    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    线程_Process实例
    线程_multiprocessing异步
    线程_multiprocessing实现文件夹copy器
    线程_GIL最简单的例子
    线程_FIFO队列实现生产者消费者
    线程_apply堵塞式
    正则表达式_合集下(后续还会有补充)
    正则表达式_合集上
    二分法查找
    数据结构_二叉树
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4656221.html
Copyright © 2011-2022 走看看