• UVA


    1、给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法。

    例如:串 abcd, 单词集合 a, b, cd, ab

    组合方式:2种:

    a,b,cd

    ab,cd

    2、把单词集合建立字典树,然后从后向前dp,dp[i]=dp[i]+dp[i+len(x)]; 其中x为当前找到的前缀长度。

    3、

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define MAX 26
    #define MOD 20071027
    
    int dp[300005];
    
    struct Trie
    {
        Trie *next[MAX];
        int v;   //根据需要变化,1代表无此单词,-1代表有此单词
    };
    Trie *root;
    
    void createTrie(char *str)
    {
        int len = strlen(str);
        Trie *p = root, *q;
        for(int i=0; i<len; ++i)
        {
            int id = str[i]-'a';
            if(p->next[id] == NULL)
            {
                // q = (Trie *)malloc(sizeof(Trie));
                q = new Trie;
                q->v = 1;    //初始v==1
                for(int j=0; j<MAX; ++j)
                    q->next[j] = NULL;
                p->next[id] = q;
            }
            p = p->next[id];
        }
        p->v = -1;   //若为结尾,则将v改成-1表示
    }
    int findTrie(char *str,int mI,int len)
    {
        int ret=0;
        //int len = strlen(str);//每次都计算,很浪费时间
        Trie *p = root;
        for(int i=mI; i<len; ++i)
        {
            int id = str[i]-'a';
            p = p->next[id];
            if(p == NULL)   //若为空集,表示不存以此为前缀的串
                return ret;
            if(p->v == -1){   //字符集中已有串是此串的前缀
                ret=(ret+dp[i+1])%MOD;
            }
        }
        return ret;
    }
    int deleteTrie(Trie* T)
    {
        int i;
        if(T==NULL)
            return 0;
        for(i=0; i<MAX; i++)
        {
            if(T->next[i]!=NULL)
                deleteTrie(T->next[i]);
        }
        //free(T);
        delete(T);
        return 0;
    }
    int main()
    {
        char str[300005];
        char str2[105];
        int i,S,len,mCase=0;
        while(~scanf("%s",str)){
            root=new Trie;
            for(i=0; i<MAX; i++)
                root->next[i]=NULL;
            memset(dp,0,sizeof(dp));
            len=strlen(str);
            scanf("%d",&S);
            while(S--){
                scanf("%s",str2);
                createTrie(str2);
            }
    
            dp[len]=1;
            for(i=len-1;i>=0;--i)
                dp[i]=findTrie(str,i,len);
    
            printf("Case %d: %d
    ",++mCase,dp[0]);
            delete(root);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    头信息已输出的报错信息位置定位
    阅读<php程序设计>笔记
    include、ruquire使用相对路径总结
    php中未定义的变量使用技巧
    Oracle官方教材(9i、10G及App 11i)
    Vista的软件兼容性
    轻松找回Vista序列号
    oralce定时执行存储过程任务设置步骤详细
    今天做了内存测试,发现真的是内存问题导致的一连串的问题
    网络邮盘(GMailStore) V3.0.2
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4945896.html
Copyright © 2020-2023  润新知