zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    CSS hack:区分IE6,IE7,firefox
    十句CSS学习顺口溜
    div css表单布局的五个小技巧
    最常用的10种CSS BUG解决方法与技巧浏览器兼容教程
    最全的CSS浏览器兼容问题
    10款浏览器CSS Reset的方法
    [MySQL技巧]INSERT … ON DUPLICATE KEY UPDATE(转)
    新手写css常犯的8个错误
    如何在页面中插入播放器
    NicTeX 网络数学公式可视化编辑器
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9626362.html
Copyright © 2011-2022 走看看