• UVALive


    https://vjudge.net/problem/UVALive-3942

    题意:给出一个字典和一个字符串,将这个字符串分解成若干个单词的连接(单词可以重复使用),问有多少种分法

    dp[i]表示以i开始(即后缀[i,L])的字符串的分解方案数

    dp[i]=Σ dp[i+len[x]] (x是[i,L]的前缀)

    判断x是否是[i,L]的前缀:

    构造字典树,

    如果在i发现了单次结尾,dp[]+=dp[i+1],不需要字典树每个节点挂一个链表

    #include<cstdio>
    #include<cstring>
    
    #define N 300001
    #define M 101
    #define mod 20071027
    using namespace std;
    
    char s[N],a[M];
    int m,len;
    int trie[M*4001][27],tot;
    int dp[N];
    int mark[M*4001];
    
    void insert(int j)
    {
        len=strlen(a);
        int root=0,id;
        for(int i=0;i<len;i++)
        {
            id=a[i]-'a';
            if(!trie[root][id]) trie[root][id]=++tot;
            root=trie[root][id];
        }
        mark[root]=j;
    }
    void find(int start,int en)
    {
        int root=0,id,ans=0;
        for(int i=start;i<=en;i++)
        {
            id=s[i]-'a';
            if(!trie[root][id]) break ;
            root=trie[root][id];
            if(mark[root]) 
            {
                ans+=dp[i+1]%mod; 
                ans%=mod;
            }
        }
        dp[start]=ans;
    }
    int main()
    {
        int t=0;
        while(scanf("%s",s)!=EOF)
        {
    
            scanf("%d",&m);
            memset(dp,0,sizeof(dp));
            memset(mark,0,sizeof(mark));
            memset(trie,0,sizeof(trie));
            for(int i=1;i<=m;i++)
            {
                scanf("%s",a);
                insert(i);
            }
            int l=strlen(s);
            dp[l]=1;
            for(int i=l-1;i>=0;i--)  find(i,l-1);
            printf("Case %d: %d
    ",++t,dp[0]);
        }
    }
  • 相关阅读:
    Typescript和React结合项目初始化
    React 和 TypeScript 如何一起使用
    Cesium取代leaflet,和Vue等前端框架结合
    cesium之3dtiles的制作问题
    Cesium-3dTiles格式详解
    TIN和等高线的关系
    CAD如何生成等高线
    Cesium风场
    cesium加载等高线
    DEM坡度和坡向分析
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6957130.html
Copyright © 2020-2023  润新知