• UVA


    https://vjudge.net/problem/UVA-1401

    题意

    给出S个不同的单词作为字典,还有一个长度最长为3e5的字符串。求有多少种方案可以把这个字符串分解为字典中的单词。

    分析

    首先强烈吐槽,vjudge上的UVALive 3942怎么都过不了。。。然而题目一模一样的UVA 1401就稳稳地过了。。。很玄学。

    根据题意可以想到一个dp,dp[i]表示从第i个字符开始的字符串的分解方案。那么dp[i]=dp[i]+dp[i+len(x)],其中单词x为匹配的前缀。

    如此,从后开始枚举i,每次都走一遍trie,找对应前缀的单词节点,然后计数。初始化dp[len]=1,为了让dp[len-1]能正确转移。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <stack>
    #include <set>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define ms(a, b) memset(a, b, sizeof(a))
    #define pb push_back
    #define mp make_pair
    #define pii pair<int, int>
    //#define eps 0.0000000001
    #define IOS ios::sync_with_stdio(0);cin.tie(0);
    #define random(a, b) rand()*rand()%(b-a+1)+a
    #define pi acos(-1)
    //const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const int inf = 0x3f3f3f3f;
    const int maxn = 3e5 + 10;
    const int maxm = 4e5 +10;
    const int mod = 20071027;
    const int sigma_size = 26;
    char s[maxn];
    ll dp[maxn];
    struct Trie{
        int ch[maxm][sigma_size];
        bool val[maxm];
        int sz;
        void init(){
            sz=1;
            memset(ch[0],0,sizeof(ch[0]));
            memset(val,0,sizeof(val));
        }
        int idx(char c) { return c-'a'; }
        void insert(char* s){
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++){
                int c = idx(s[i]);
                if(!ch[u][c]){
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=false;
                    ch[u][c]=sz++;
                }
                u=ch[u][c];
            }
            val[u]=true;
        }
        void query(char* s){
            int len=strlen(s);
            memset(dp,0,sizeof(dp));
            dp[len]=1;
            for(int i=len-1;i>=0;i--){
                int u=0;
                for(int j=i;j<len;j++){
                    int c = idx(s[j]);
                    if(!ch[u][c]) break;
                    u=ch[u][c];
                    if(val[u]) dp[i]=(dp[i]+dp[j+1])%mod;
                }
            }
        }
    };
    Trie trie;
    char tmp[110];
    int main() {
    #ifdef LOCAL
        freopen("in.txt", "r", stdin);
    //    freopen("input.txt", "w", stdout);
    #endif
        int cas=1;
        while(~scanf("%s",s)){
            trie.init();
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%s",tmp);
                trie.insert(tmp);
            }
            trie.query(s);
            printf("Case %d: %lld
    ",cas++,dp[0]);
        }
        return 0;
    }
  • 相关阅读:
    python多版本切换
    python之禅
    Python int与string之间的转化
    pycharm工具使用
    python学习路线图
    traceback.print_exc()的用法
    他人学习Python感悟
    【西北师大-19软工】第十三、十四次作业汇总暨期末总结
    【西北师大-19软工】第十二次作业成绩汇总
    第十七周助教工作总结——NWNU李泓毅
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9626362.html
Copyright © 2020-2023  润新知