UVA 1401 Remember the Word(Trie树 套 DP)

来源:互联网 发布:哪个软件可以看韩剧 编辑:程序博客网 时间:2024/05/28 05:13

【题意】给出一个有S个不同单词组成的字典和一个字符串。把这个字符串分解成若干个单词的连接,有多少种方法?

【解题方法】令dp[i]表示以字符i结束的字符串的分解方案数,即dp[i+j] = sum(dp[i]) (j为一个单词的长度),初始化dp[0] = 1;把所有单词组成Trie,然后试着在Trie中查找单词即可。

【代码君】

////Created by just_sort 2016/10/12//Copyright (c) 2016 just_sort.All Rights Reserved//#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 444444;const int maxm = 26;const int mod =  20071027;int dp[333333];char s[333333];struct Trie{    int ch[maxn][maxm],val[maxn],root,sz;    int newnode(){        val[sz] = 0;        memset(ch[sz],0,sizeof(ch[sz]));        return sz++;    }    void init(){        sz = 0;        root = newnode();    }    void insert(char *s,int v){        int len = strlen(s);        int u = root;        for(int i = 0; i < len; i++){            int now = s[i] - 'a';            if(!ch[u][now]){                ch[u][now] = newnode();            }            u = ch[u][now];        }        val[u] = v;    }//    int find(char *s){//        int len = strlen(s);//        int u = root;//        for(int i = 0; i < len; i++){//            int now = s[i] - 'a';//            if(!ch[u][now]) return 0;//            u = ch[u][now];//        }//        return val[u];//    }}trie;int main(){    int ks = 1, n;    while(scanf("%s",s+1)!=EOF)    {        trie.init();        scanf("%d",&n);        for(int i = 1; i <= n; i++){            char op[110];            scanf("%s",op);            trie.insert(op, 1);        }        int len = strlen(s+1);        memset(dp, 0, sizeof(dp));        dp[0] = 1; s[0] = '$';        for(int i = 0; s[i]; i++)        {            int u = 0;            for(int j = 1; j <= len; j++){                int now = s[i+j] - 'a';                u = trie.ch[u][now];                if(!u) break;                else if(trie.val[u] == 1){                    dp[i+j] = (dp[i+j] + dp[i]) % mod;                }            }        }        printf("Case %d: %d\n",ks++,dp[len]);    }    return 0;}


0 0