UVALive 3942 Remember the Word

来源:互联网 发布:淘宝的子账号是什么 编辑:程序博客网 时间:2024/05/17 02:59

利用Trie树进行转移

#include<cstdio>#include<cstring>#define MAXN 400003#define SN 26#define MAXL 300003#define MOD 20071027using namespace std;struct Trie {    Trie *s[SN];    bool end;    void clear() {        memset(s, 0, sizeof(s));        end=false;    }}trie[MAXN];char str[MAXL], tmp[103];int n, tot, dp[MAXL];void insert() {    Trie *cur=&trie[0];    for(int i=0; tmp[i]; ++i) {        int p=tmp[i]-'a';        if(!cur->s[p]) {            trie[tot].clear();            cur->s[p]=&trie[tot++];        }        cur=cur->s[p];    }    cur->end=true;}int l;void chk(int add,int jmp) {    Trie *cur=&trie[0];    for(int i=jmp;i<=l;i++){        if(cur->s[str[i]-'a']){            cur=cur->s[str[i]-'a'];            if(cur->end)                dp[i]=(dp[i]+add)%MOD;        }        else break;    }}int main() {    for(int cas=1; scanf("%s",&str[1])!=EOF; ++cas) {        scanf("%d", &n);        trie[0].clear();        tot=1;        for(int i=0; i<n; ++i) {            scanf("%s", tmp);            insert();        }        memset(dp, 0, sizeof(dp));        dp[0]=1;        l=strlen(&str[1]);       //dp[i]表示由所给字符串组成(1~i)部分的源串的方法数        for(int i=1; i<=l; ++i) {            if(dp[i-1])                chk(dp[i-1],i);  //这里迭代是由dp[i-1]根据源串推导dp[j](i=<j<=l)        }        printf("Case %d: %d\n", cas, dp[l]);    }    return 0;}



原创粉丝点击