码迷,mamicode.com
首页 > 其他好文 > 详细

UVA - 1401 Remember the Word(trie+dp)

时间:2015-11-07 20:20:30      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

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\n",++mCase,dp[0]);
        delete(root);
    }
    return 0;
}
View Code

 

UVA - 1401 Remember the Word(trie+dp)

标签:

原文地址:http://www.cnblogs.com/bofengyu/p/4945896.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!