Gym - 101174E Passwords AC自动机+额外的限制条件+状态压缩dp
2017-10-07 09:57
447 查看
My Solution 题意:给出n个由小写字母模式串,用大写字母、小写字母、十进制数字构造的长度为[A, B]的字符串, 且满足一下限制条件:1、必须有至少一个大写字母至少一个小写字母和一个数字。 2、不包含任一模式串(不区分大小写)。 3、对于o、i、e、s、t,在模式串时和0、1、3、5、7不区分。 求构造出的满足条件的字符串种数。 AC自动机+额外的限制条件+状态压缩dp 首先这题的原始版本是 给出n模式串,构造不含任一模式串的长度为m的字符串种类数 http://blog.csdn.net/prolightsfxjh/article/details/54729646。 然后这题添加1、用大小写+数字进行构造+不区分大小写。 2、 构造出的字符串有至少一个大写字母至少一个小写字母和一个数字。 3、对于o、i、e、s、t,在模式串时和0、1、3、5、7不区分。 对于第二个条件,可以直接添加一维dp[8] 来状态压缩。 对于第一个条件则转移的时候直接转移2次即可,//mod( dp[ac.ch[j][k]][i][w | 1] += dp[j][i-1][w] ); mod( dp[ac.ch[j][k]][i][w | 2] += dp[j][i-1][w] ); 对于第三个条件则如果是o、i、e、s、t 则在不是危险节点的时候额外转移一次,//mod( dp[ac.ch[j][k]][i][w | 4] += dp[j][i-1][w] ); 其它数字则不管当前节点是否为危险节点都进行转移。 答案就是 sigma{dp[0 ~ ac.sz][[A, B]]} 复杂度 O(max(A, B) * len* n * 8 * CHAR_SIZE) == 4.16e6
抄https://vjudge.net/solution/10950867的..
代码不知道什么地方错了.
参考:http://blog.csdn.net/prolightsfxjh/article/details/75453051
#include<bits/stdc++.h> using namespace std; #define sf scanf #define pf printf #define mem(a,b) memset(a,b,sizeof(a)); #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define MP make_pair #define pii pair<int,int> #define ULL unsigned long long #define LL long long #define md ((ll+rr)>>1) #define ls (i<<1) #define rs (ls|1) #define ree freopen("in.txt","r",stdin); #define bug pf("----------------"); #define N 2010 #define M 20020 #define INF 1e9 #define inf 0x3f3f3f3f #define mod 1000003 #define chr 26 int dp[8][22][2010]; inline void add(int &x,int y){ x+=y; x%=mod; } char jd[5]={'o','i','e','s','t'}; bool fk(int x){ for(int i=0;i<5;++i) if(x==jd[i]-'a')return 1; return 0; } struct Tire{ int nex [chr],fail ; bool end ; int rt,L; int newnode(){ for(int i=0;i<chr;++i) nex[L][i]=-1; end[L++]=0; return L-1; } void init(){ L=0; rt=newnode(); } void insert(char buf[]){ int len=strlen(buf); int now=rt; for(int i=0;i<len;++i){ int c=buf[i]-'a'; int now=rt; for(int i=0;i<len;++i){ int c=buf[i]-'a'; if(nex[now][c]==-1) nex[now][c]=newnode(); now=nex[now][c]; } end[now]=1; } } void build(){ queue<int>Q; fail[rt]=rt; for(int i=0;i<chr;++i) if(nex[rt][i]==-1) nex[rt][i]=rt; else{ fail[nex[rt][i]]=rt; Q.push(nex[rt][i]); } while(!Q.empty()){ int now=Q.front(); Q.pop(); if(end[fail[now]])end[now]=1; for(int i=0;i<chr;++i) if(nex[now][i] 4000 ==-1) nex[now][i]=nex[fail[now]][i]; else{ fail[nex[now][i]]=nex[fail[now]][i]; Q.push(nex[now][i]); } } } void solve(int le,int ri){ dp[0][0][0]=1; for(int i=0;i<ri;++i){ for(int j=0;j<L;++j){ for(int sta=0;sta<8;++sta){ if(!dp[sta][i][j])continue; add(dp[sta|1][i+1][0],dp[sta][i][j]*5); for(int k=0;k<chr;++k){ int c=nex[j][k]; if(end[c])continue; add(dp[sta|2][i+1][c],dp[sta][i][j]); add(dp[sta|4][i+1][c],dp[sta][i][j]); if(fk(k))add(dp[sta|1][i+1][c],dp[sta][i][j]); } } } } int ans=0; for(int i=le;i<=ri;++i) for(int j=0;j<L;++j) add(ans,dp[7][i][j]); pf("%d\n",ans); } }ac; int L,R,n; char s ; int main(){ sf("%d%d%d",&L,&R,&n); ac.init(); for(int i=1;i<=n;++i){ sf("%s",s); ac.insert(s); } ac.build(); ac.solve(L,R); }
相关文章推荐
- Gym - 101174E Passwords AC自动机+额外的限制条件+状态压缩dp
- Codeforces Gym 101173B / BZOJ 4788 Bipartite Blanket 二分图Hall定理+状态压缩DP
- Codeforces Gym 100015F Fighting for Triangles 状态压缩DP
- 2018年全国多校算法寒假训练营练习比赛(第二场) F 德玛西亚万岁(状态压缩DP 未解决)
- hdu 4628(状态压缩dp)
- POJ 3254 (基础 状态压缩 DP )
- CF - 580D. Kefa and Dishes - 状态压缩DP
- POJ 2411 状态压缩DP
- POJ 3254 炮兵阵地(状态压缩DP)
- pojPOJ 2411--Mondriaan's Dream+状态压缩dp
- [状态压缩]---区间dp第一题
- SGU223 状态压缩DP
- poj 1015 Jury Compromise 状态压缩DP(不压缩也行)
- poj3254(状态压缩dp)
- POJ--1185--炮兵阵地--状态压缩DP
- poj1185(状态压缩dp)
- hdu 2167 状态压缩dp(入门题目)
- [poj 2411]Mondriaan's Dream[状态压缩DP]
- HDU 1074Doing Homework(状态压缩dp)
- poj3254 状态压缩dp