zoukankan      html  css  js  c++  java
  • POJ1625 Censored! —— AC自动机 + DP + 大数

    题目链接:https://vjudge.net/problem/POJ-1625

    Censored!
    Time Limit: 5000MS   Memory Limit: 10000K
    Total Submissions: 10870   Accepted: 2979

    Description

    The alphabet of Freeland consists of exactly N letters. Each sentence of Freeland language (also known as Freish) consists of exactly M letters without word breaks. So, there exist exactly N^M different Freish sentences. 

    But after recent election of Mr. Grass Jr. as Freeland president some words offending him were declared unprintable and all sentences containing at least one of them were forbidden. The sentence S contains a word W if W is a substring of S i.e. exists such k >= 1 that S[k] = W[1], S[k+1] = W[2], ...,S[k+len(W)-1] = W[len(W)], where k+len(W)-1 <= M and len(W) denotes length of W. Everyone who uses a forbidden sentence is to be put to jail for 10 years. 

    Find out how many different sentences can be used now by freelanders without risk to be put to jail for using it. 

    Input

    The first line of the input file contains three integer numbers: N -- the number of letters in Freish alphabet, M -- the length of all Freish sentences and P -- the number of forbidden words (1 <= N <= 50, 1 <= M <= 50, 0 <= P <= 10). 

    The second line contains exactly N different characters -- the letters of the Freish alphabet (all with ASCII code greater than 32). 

    The following P lines contain forbidden words, each not longer than min(M, 10) characters, all containing only letters of Freish alphabet. 

    Output

    Output the only integer number -- the number of different sentences freelanders can safely use.

    Sample Input

    2 3 1
    ab
    bb
    

    Sample Output

    5
    

    Source

    Northeastern Europe 2001, Northern Subregion

    题意:

    给出p个单词,求长度为m且不含有已给单词的字符串有多少个?其中字母表有n个字母。

    题解:

    POJ2278 DNA Sequence无异,只不过此题没有取模,而答案可能很大,所以用到高精度。而且字符串长度较小,可以直接用动态规划进行求解,而不需要用到矩阵进行加速。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const double EPS = 1e-6;
     15 const int INF = 2e9;
     16 const LL LNF = 9e18;
     17 const int MOD = 1e5;
     18 const int MAXN = 50*50+10;
     19 
     20 struct BigInt
     21 {
     22     const static int mod = 10000;
     23     const static int DLEN = 4;
     24     int a[100],len;
     25     BigInt()
     26     {
     27         memset(a,0,sizeof(a));
     28         len = 1;
     29     }
     30     BigInt(int v)
     31     {
     32         memset(a,0,sizeof(a));
     33         len = 0;
     34         do
     35         {
     36             a[len++] = v%mod;
     37             v /= mod;
     38         }while(v);
     39     }
     40     BigInt operator +(const BigInt &b)const
     41     {
     42         BigInt res;
     43         res.len = max(len,b.len);
     44         for(int i = 0;i <= res.len;i++)
     45             res.a[i] = 0;
     46         for(int i = 0;i < res.len;i++)
     47         {
     48             res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
     49             res.a[i+1] += res.a[i]/mod;
     50             res.a[i] %= mod;
     51         }
     52         if(res.a[res.len] > 0)res.len++;
     53         return res;
     54     }
     55     void output()
     56     {
     57         printf("%d",a[len-1]);
     58         for(int i = len-2;i >=0 ;i--)
     59             printf("%04d",a[i]);
     60         printf("
    ");
     61     }
     62 };
     63 
     64 BigInt dp[2][MAXN];
     65 int M[128];
     66 struct Trie
     67 {
     68     int sz, base;
     69     int next[MAXN][50], fail[MAXN], end[MAXN];
     70     int root, L;
     71     int newnode()
     72     {
     73         for(int i = 0; i<sz; i++)
     74             next[L][i] = -1;
     75         end[L++] = false;
     76         return L-1;
     77     }
     78 
     79     void init(int _sz, int _base)
     80     {
     81         sz = _sz;
     82         base = _base;
     83         L = 0;
     84         root = newnode();
     85     }
     86     void insert(char buf[])
     87     {
     88         int len = strlen(buf);
     89         int now = root;
     90         for(int i = 0; i<len; i++)
     91         {
     92             if(next[now][M[buf[i]]] == -1) next[now][M[buf[i]]] = newnode();
     93             now = next[now][M[buf[i]]];
     94         }
     95         end[now] |= true;
     96     }
     97     void build()
     98     {
     99         queue<int>Q;
    100         fail[root] = root;
    101         for(int i = 0; i<sz; i++)
    102         {
    103             if(next[root][i] == -1) next[root][i] = root;
    104             else fail[next[root][i]] = root, Q.push(next[root][i]);
    105         }
    106         while(!Q.empty())
    107         {
    108             int now = Q.front();
    109             Q.pop();
    110             end[now] |= end[fail[now]];
    111             for(int i = 0; i<sz; i++)
    112             {
    113                 if(next[now][i] == -1) next[now][i] = next[fail[now]][i];
    114                 else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
    115             }
    116         }
    117     }
    118 
    119     void query(int len)
    120     {
    121         for(int i = 0; i<=1; i++)
    122         for(int j = 0; j<L; j++)
    123             dp[i][j] = 0;
    124 
    125         int cur = 0;
    126         dp[cur][root] = 1;
    127         for(int i = 0; i<len; i++)
    128         {
    129             for(int j = 0; j<L; j++)
    130                 dp[cur^1][j] = 0;
    131             for(int j = 0; j<L; j++)
    132             {
    133                 if(end[j]) continue;
    134                 for(int k = 0; k<sz; k++)
    135                 {
    136                     if(end[next[j][k]]) continue;
    137                     dp[cur^1][next[j][k]] = dp[cur^1][next[j][k]] + dp[cur][j];
    138                 }
    139             }
    140             cur ^= 1;
    141         }
    142 
    143         BigInt ret = 0;
    144         for(int i = 0; i<L; i++)
    145             ret = ret + dp[cur][i];
    146         ret.output();
    147     }
    148 };
    149 
    150 Trie ac;
    151 char buf[MAXN];
    152 int main()
    153 {
    154     int n, m, p;
    155     while(scanf("%d%d%d", &n,&m,&p)!=EOF)
    156     {
    157         ac.init(n, 0);
    158         scanf("%s", buf);
    159         for(int i = 0; buf[i]; i++)
    160             M[buf[i]] = i;
    161         for(int i = 1; i<=p; i++)
    162         {
    163             scanf("%s", buf);
    164             ac.insert(buf);
    165         }
    166         ac.build();
    167         ac.query(m);
    168     }
    169 }
    View Code
  • 相关阅读:
    Mybatis-Plus02 CRUD
    Idea一直卡在loading archetype list问题解决(或者报Unable to import maven project: See logs for details)
    Mybatis-Plus01 快速开始
    用PS给视频磨皮美颜
    Linux基本内容
    【maven】IDEA工程右边的maven配置中Plugins有重复的命令
    段誉身具凌波微波,动无常则,若危若安,一次能走一级台阶或者两级台阶,他要爬一段30级的山路,问有多少种走法?分析如何计算,然后编程解答。 进阶问题:当他轻功熟练度提升,一次最多可以走三级,那就结果有什么变化?后来走火入魔了,不能走一级,只能走二或三级,又有什么变化?
    小陆每天要写一份工作日报,日报标题含有日期。几年后,他翻开以前的日报,想知道两份日报的日期是否同为星期几,请编程帮助他判断。
    高性能HTML5/JS开发框架DevExtreme 新版——v20.2.7发布
    跨平台UI开发框架DevExpress XAF 拥有超强性能,你Get了吗?
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8459493.html
Copyright © 2011-2022 走看看