zoukankan      html  css  js  c++  java
  • UVALive 3942 Remember The Word (Tire)

    状态是DAG,因此方案用dp统计,dp[i] = sum(dp[i+len(x)]),x是以i开头的前缀且是单词,关键在于快速判断一个前缀是不是单词,可用Trie。

    每一次转移的复杂度是O(maxlen),maxlen是单词的最长长度。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 4005*100//4000*98+26*26+26+1
    ,sigma_size = 26;
    
    
    int ch[maxn][sigma_size];
    bool vis[maxn];
    int nd_cnt;
    
    const int LEN = 3e5+5, mod = 20071027;
    char str[LEN];
    int d[LEN];
    
    void init()
    {
        nd_cnt = 1; memset(ch[0],0,sizeof(ch[0]));
    }
    
    void add(char *s)
    {
        int u = 0;
        int n = strlen(s);
        for(int i = 0; i < n; i++){
            int c = word[i]-'a';
            if(!ch[u][c]){
                memset(ch[nd_cnt],0,sizeof(ch[nd_cnt]));
                vis[nd_cnt] = false;
                ch[u][c] = nd_cnt++;
            }
            u = ch[u][c];
        }
        vis[u] = true;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        char word[120];
        int kas = 0;
        while(gets(str)){
            init();
            int S; scanf("%d
    ",&S);
            while(S--){
                gets(word);
                add(word);
            }
            int n = strlen(str);
            d[n] = 1;
            for(int cur = n-1; cur >= 0; cur--){
                int u = 0; d[cur] = 0;
                for(int i = cur; i < n; i++){
                    int c = str[i]-'a';
                    if(!ch[u][c]) break;
                    u = ch[u][c];
                    if(vis[u]) d[cur] += d[i+1];
                }
                d[cur] %= mod;
            }
            printf("Case %d: %d
    ",++kas,d[0]);
        }
        return 0;
    }
  • 相关阅读:
    线程、同步
    异常、线程
    Map
    List、Set
    Collection、泛型
    Object类、常用API
    h5-上传图片预览
    js 获取get参数
    《转》完美解决微信video视频隐藏控件和内联播放问题
    写入文件(覆盖文件的内容)
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4793580.html
Copyright © 2011-2022 走看看