POJ 1625 Censored!(AC自动机,DP)
来源:互联网 发布:出售欧美邮箱数据 编辑:程序博客网 时间:2024/05/17 06:51
http://poj.org/problem?id=1625
Censored!
Time Limit: 5000MS Memory Limit: 10000KTotal Submissions: 8266 Accepted: 2229
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.
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.
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 1abbb
Sample Output
5
Source
Northeastern Europe 2001, Northern Subregion
题意:
给出一n种字符的字典,有k个禁用的单词,问能组成多少个不同的长度为m的合法字符串。
分析:
构建出AC自动机后在里面走m步有不经过单词结点有多少种方案,用dp[i][j]表示走了i步到第j个结点的方案数,根据计数原理可得状态转移方程:dp[i][j]=sum(dp[i][last_j]),其中last_j表示能走到j结点的前趋们,j不为单词结点。要注意此题要用到高精度,而且要用unsigned char存储。
/* * * Author : fcbruce <fcbruce8964@gmail.com> * * Time : Thu 20 Nov 2014 11:43:12 AM CST * */#include <cstdio>#include <iostream>#include <sstream>#include <cstdlib>#include <algorithm>#include <ctime>#include <cctype>#include <cmath>#include <string>#include <cstring>#include <stack>#include <queue>#include <list>#include <vector>#include <map>#include <set>#define sqr(x) ((x)*(x))#define LL long long#define itn int#define INF 0x3f3f3f3f#define PI 3.1415926535897932384626#define eps 1e-10#ifdef _WIN32 #define lld "%I64d"#else #define lld "%lld"#endif#define maxm #define maxn 512using namespace std;unsigned char dict[64],P[16];char str[233];int q[maxn];const int maxl = 16;struct bign{ static int width; static long long mod; int len; long long s[maxl]; bign() { memset(s,0,sizeof s); len=1; } bign operator = (int num) { char s[maxl]; sprintf(s,"%d",num); *this=s; return *this; } bign operator = (const char *s) { int l=strlen(s); len=0; for (int i=l-1;i>=0;i-=width,len++) { (*this).s[len]=0; for (int j=max(0,i-width+1);j<=i;j++) (*this).s[len]=(*this).s[len]*10+s[j]-'0'; } return *this; } void str(char *s) { char format[10]; sprintf(format,"%%0%d%s",width,lld+1); for (int i=len-1,j=0;i>=0;i--,j++) sprintf(s+j*width,format,(*this).s[i]); int j=0; while (s[j]=='0' && s[j+1]!='\0') j++; strcpy(s,s+j); } bign operator + (const bign &b)const { bign c; c.len=0; long long g=0ll; for (itn i=0;g!=0ll || i<max(len,b.len);i++) { long long x=g; if (i<len) x+=s[i]; if (i<b.len) x+=b.s[i]; c.s[c.len++]=x%mod; g=x/mod; } return c; }}dp[2][maxn];int bign::width=8;long long bign::mod=100000000ll;const int maxsize = 50;struct ACauto{ int ch[maxn][maxsize]; bool val[maxn]; int nex[maxn]; int sz,maxs; ACauto() { memset(ch[0],0,sizeof ch[0]); val[0]=false; sz=1; } int idx(unsigned char c) { for (int i=0;i<maxs;i++) if (dict[i]==c) return i; return -1; } void insert(const unsigned char *s) { int u=0; for (int i=0;s[i]!='\0';i++) { int c=idx(s[i]); if (ch[u][c]==0) { memset(ch[sz],0,sizeof ch[sz]); val[sz]=false; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=true; } void get_fail() { int f=0,r=-1; nex[0]=0; for (int c=0;c<maxs;c++) { int u=ch[0][c]; if (u!=0) { nex[u]=0; q[++r]=u; } } while (f<=r) { int x=q[f++]; for (int c=0;c<maxs;c++) { int u=ch[x][c]; if (u==0) { ch[x][c]=ch[nex[x]][c]; continue; } q[++r]=u; int v=nex[x]; nex[u]=ch[v][c]; val[u]|=val[nex[u]]; } } } bign DP(int l) { for (int i=0;i<sz;i++) dp[0][i]=0; dp[0][0]=1; int x=1; for (int i=0;i<l;i++,x^=1) { for (int j=0;j<sz;j++) dp[x][j]=0; for (int j=0;j<sz;j++) { for (int c=0;c<maxs;c++) { if (val[ch[j][c]]) continue; dp[x][ch[j][c]]=dp[x][ch[j][c]]+dp[x^1][j]; } } } bign total; for (int i=0;i<sz;i++) total=total+dp[x^1][i]; return total; }}acauto;void read(unsigned char *P){ int i=0; while ((P[i]=getchar())!='\n') i++; P[i]=0;}int main(){#ifdef FCBRUCE freopen("/home/fcbruce/code/t","r",stdin);#endif // FCBRUCE int n,m,p; scanf("%d%d%d",&n,&m,&p);getchar(); acauto.maxs=n; for (int i=0;i<n;i++) dict[i]=getchar(); getchar(); for (int i=0;i<p;i++) { read(P); acauto.insert(P); } acauto.get_fail(); acauto.DP(m).str(str); printf("%s\n",str); return 0;}
2 0
- poj 1625 Censored!//AC自动机+DP+大数
- POJ--1625[Censored!] AC自动机+DP+高精度
- POJ 1625 Censored【AC自动机+DP+大数】
- POJ 1625 Censored!(AC自动机+DP)
- 【AC自动机+DP+大数】 POJ 1625 Censored!
- poj 1625 Censored!(AC自动机+DP+高精度)
- POJ 1625 Censored!(AC自动机,DP)
- poj 1625 Censored! (ac自动机+dp)
- poj 1625 Censored! AC自动机+dp+高精度
- [AC自动机+dp+高精度] poj 1625 Censored!
- POJ 1625 Censored(AC自动机+dp)
- POJ 1625 Censored! AC自动机+DP+高精度 *
- POJ 1625 Censored!(AC自动机+DP)
- poj 1625 Censored! 【AC自动机 + DP + 强力大数模版】
- poj 1625 Censored! AC自动机+DP +高精度 + C艹 + java
- POJ 1625 Censored! AC自动机 简单DP 高精度
- POJ 1625 Censored! (AC自动机+DP+高精度,5级)
- poj 1625 Censored!(AC自动机+DP+高精)
- OpenGL超级宝典 5e 环境配置
- 进一步解 apt-get 的几个命令
- jquery 实现 点击按钮后倒计时效果,多用于实现发送手机验证码、邮箱验证码
- android学习—— context 和 getApplicationContext()
- 嵌入式 vim配置精华
- POJ 1625 Censored!(AC自动机,DP)
- Photoshop脚本 > 创建一个选区
- 目标检测的图像特征提取之(二)LBP特征
- 数组大折腾2
- 十三周项目一 3
- jquery/js中如何判断字符串为null值
- 第十三周项目一数组大折腾(3)
- Jenkins插件之Publish Over SSH/CIFS/FTP
- Andriod 从源码的角度详解View,ViewGroup的Touch事件的分发机制