zoukankan      html  css  js  c++  java
  • UVA1401 Remember the Word

    刘汝佳新书--训练指南

    题意:给出N个不同单词和一个长字符串S。把这个字符串分解成若干个单词的连接(单词尅重复使用),问有多少种方法?

    分析:令d[i]表示从字符i开始的字符串的分解方案数,则dans[i]=sum{dans[i+d[x]] | 单词x是S[i...len]的前缀};

    // File Name: 1401.cpp
    // Author: zlbing
    // Created Time: 2013/3/14 18:55:52
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,n) for(int i=0;i<n;i++)
    #define REP1(i,n) for(int i=1;i<n+1;i++)
    const int maxnode=4000*100+10;
    const int sigma_size=26;
    
    // 字母表为全体小写字母的Trie
    struct Trie {
      int ch[maxnode][sigma_size];
      int val[maxnode];
      int sz; // 结点总数
      void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } // 初始时只有一个根结点
      int idx(char c) { return c - 'a'; } // 字符c的编号
    
      // 插入字符串s,附加信息为v。注意v必须非0,因为0代表“本结点不是单词结点”
      void insert(const char *s, int v) {
        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] = 0;  // 中间结点的附加信息为0
            ch[u][c] = sz++; // 新建结点
          }
          u = ch[u][c]; // 往下走
        }
        val[u] = v; // 字符串的最后一个字符的附加信息为v
      }
      void find_prefix(char *s,int len,vector<int>& ans){
         // int len=strlen(s);每次找前缀时都算一次长度,要算10^5次,因此导致超时了。。。又这长度是有规律的,因此可以事先算出来
          int u=0;
          for(int i=0;i<len;i++){
              if(s[i]=='\0')break;
            int c=idx(s[i]);
            if(ch[u][c]){
                u=ch[u][c];
                if(val[u])ans.push_back(val[u]);
            }else break;
          }
      }
    };
    Trie solver;
    char str[300050];
    int d[4005];
    int dans[300050];
    const int MOD=20071027;
    int main(){
        int cas=0;
        while(~scanf("%s",str)){
            int n;
            scanf("%d",&n);
            solver.clear();
            char word[105];
            REP1(i,n){
                scanf("%s",word);
                int len=strlen(word);
                d[i]=len;
                solver.insert(word,i);
            }
            int len=strlen(str);
            CL(dans,0);
            dans[len]=1;
            for(int i=len-1;i>=0;i--){
                vector<int> ans;
                solver.find_prefix(str+i,len-i,ans);
                for(int j=0;j<ans.size();j++){
                    dans[i]=(dans[i]+dans[i+d[ans[j]]])%MOD;
                }
            }
            printf("Case %d: %d\n",++cas,dans[0]);
        }
        return 0;
    }
  • 相关阅读:
    智慧养老民政监管平台建设方案
    CF600E Lomsat gelral dsu on tree
    dsu on tree详解
    【Spring 从0开始】Spring5 新功能,整合日志框架 Log4j2
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 数据库事务参数
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 操作数据库
    【Spring 从0开始】AOP 操作
    【Spring 从0开始】AOP 操作中的相关术语、环境准备
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2960260.html
Copyright © 2011-2022 走看看