Uva1401/LA3942 Remember the Word(trie模板)

来源:互联网 发布:北京邮电大学软件学院 编辑:程序博客网 时间:2024/05/15 10:18

LRJ书上例题,但是自己在思考过程中挺有收获。。。。
UVA1401题目直达
题目大意是拆解字符串,有几种方法。
简单思路:设dp[i]为字符串从第i位开始的拆解方法;仔细一想的话就会发现这样的关系:

dp[i]=j[1,S]dp[i+len[j]]

其中S为单词总数,j为单词编号。
使用trie可以实现,AC代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;const int maxn=500000;const int mod=20071027;char buffer[maxn];int dp[maxn];int mark[maxn];char word[5000][200];int n;    int val[maxn];    int ch[maxn][27];    int sz;    void ini()    {        sz=1;        memset(val,0,sizeof(val));        memset(ch,0,sizeof(ch));        memset(dp,0,sizeof(dp));        memset(mark,0,sizeof(mark));        memset(word,0,sizeof(word));    }    int ind(char c)    {        return c-'a';    }    void insert(char *s,int v)    {        int len=strlen(s);        int u=0;        for(int i=0;i<len;i++)        {            int num=ind(s[i]);            if(!ch[u][num])            {                ch[u][num]=sz;                sz++;            }            u=ch[u][num];        }        val[u]=v;    }    bool queryeach(char *s)    {        int parent=0;        int len=strlen(s);        for(int i=0;i<len;i++)        {            int num=ind(s[i]);            if(ch[parent][num]==0)            {                return false;            }            parent=ch[parent][num];        }        return (val[parent]>0);    }    vector<int > query(char *s)    {        int parent=0;        vector<int > ans;        int len=strlen(s);        for(int i=0;i<len;i++)        {            int num=ind(s[i]);            if(!ch[parent][num])            {                break;            }            if(val[ch[parent][num]]!=0)            {                ans.push_back(val[ch[parent][num]]);            }            parent=ch[parent][num];        }        /*        for(unsigned i=0;i<ans.size();i++)        {            printf("%d ",ans[i]);        }        printf("\n");        */        return ans;    }char kagami[maxn];int main(){    //freopen("1.out","w",stdout);    int cas=0;    while(~scanf("%s",buffer))    {        cas++;        scanf("%d",&n);        ini();        int maxlen=0;        for(int i=0;i<n;i++)        {            memset(kagami,0,sizeof(kagami));            scanf("%s",kagami);            int len=strlen(kagami);            mark[len]++;            maxlen=max(maxlen,len);            strcpy(word[i],kagami);            insert(kagami,len);        }        //初始化        int len=strlen(buffer);        for(int i=1;i<=maxlen;i++)        {            if(mark[i]>0)            {                bool flag=queryeach(buffer+len-i);                if(flag)                {                    dp[len-i]=(dp[len-i]+1+mod)%mod;                }            }        }        /*        for(int i=0;i<=len;i++)        {            printf("dp[%d]=%d\n",i,dp[i]);        }        printf("\n");        */        dp[len]=0;        for(int i=len-1;i>=0;i--)        {            vector<int> res=query(buffer+i);            /*            for(unsigned j=0;j<res.size();j++)            {                printf("res[%d]=%d\n",j,res[j]);            }            printf("\n");            */            for(unsigned j=0;j<res.size();j++)            {                dp[i]=(dp[i]+dp[i+res[j]]+mod)%mod;            }        }        /*        for(int i=0;i<=len;i++)        {            printf("dp[%d]=%d\n",i,dp[i]);        }        */        printf("Case %d: %d\n",cas,(dp[0]+mod)%mod);    }    return 0;}

调了一段时间,不过收获还是比较大的。

0 0