bzoj 3530 : [Sdoi2014]数数
2017-02-23 22:47
453 查看
一眼AC自动机上DP,f[i][j][0]到第j个节点表示前i位与n一样的方案,1表示不一样的方案。
事实证明我每回写数位dp都要wa到神志模糊,数据一有0就跪,所以加了各种特判。。。
因为如果数据中有0032这种的话直接dp会把32判为不合法,而事实上它是合法的,因为要去掉前缀0.
所以每回从根向0的边转移时要少转移1,相当于把0000....这个全为0的前缀保留在根,为了保留这个前缀还要从第二次开始每次f[i][0][1]++。
好像每次写数位dp都是加了一堆特判才过的。。。
事实证明我每回写数位dp都要wa到神志模糊,数据一有0就跪,所以加了各种特判。。。
因为如果数据中有0032这种的话直接dp会把32判为不合法,而事实上它是合法的,因为要去掉前缀0.
所以每回从根向0的边转移时要少转移1,相当于把0000....这个全为0的前缀保留在根,为了保留这个前缀还要从第二次开始每次f[i][0][1]++。
好像每次写数位dp都是加了一堆特判才过的。。。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define p 1000000007 using namespace std; int m,n; char s[2000]; int ch[2000][10];int cnt; bool v[2000]; bool flag; void build() { int len=strlen(s); int now=0; for(int i=0;i<len;i++) { int c=s[i]-'0'; if(ch[now][c])now=ch[now][c]; else { ch[now][c]=++cnt; now=ch[now][c]; } } v[now]=1; } queue<int>q; int f[2000]; int ans; void AC() { for(int i=0;i<10;i++) { if(ch[0][i])q.push(ch[0][i]); } while(!q.empty()) { int tmp=q.front();q.pop(); for(int i=0;i<10;i++) { if(ch[tmp][i]) { f[ch[tmp][i]]=ch[f[tmp]][i]; q.push(ch[tmp][i]); if(v[f[ch[tmp][i]]])v[ch[tmp][i]]=1; } else { ch[tmp][i]=ch[f[tmp]][i]; } } } } int now[2000][2],pre[2000][2]; char a[2000]; int be[2000]; int main() { scanf("%s",a); n=strlen(a); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s",s); build(); } AC(); pre[0][0]=1; for(int i=0;i<n;i++) { int x=a[i]-'0'; if(i)pre[0][1]++; for(int j=0;j<=cnt;j++) { if(v[j])continue; for(int k=0;k<x;k++) { if(!i&&!k)continue; now[ch[j][k]][1]+=pre[j][0]; now[ch[j][k]][1]%=p; } now[ch[j][x]][0]+=pre[j][0]; now[ch[j][x]][0]%=p; for(int k=0;k<10;k++) { now[ch[j][k]][1]+=pre[j][1]-(!j&&k==0&&i!=0); now[ch[j][k]][1]%=p; } } for(int j=0;j<=cnt;j++) { if(v[j])continue; if(i==n-1) { ans+=now[j][1]; if(ans>=p)ans-=p; ans+=now[j][0]; if(ans>=p)ans-=p; } pre[j][0]=now[j][0]; pre[j][1]=now[j][1]; now[j][0]=now[j][1]=0; } } printf("%d\n",ans); return 0; }
相关文章推荐
- [bzoj3530][SDOI2014]数数
- [BZOJ 3530][Sdoi 2014]数数
- Bzoj3530 [Sdoi2014]数数
- bzoj 3530: [Sdoi2014]数数
- bzoj3530 [Sdoi2014]数数(AC自动机+数位DP)
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位DP)
- 【BZOJ3530】[Sdoi2014]数数 AC自动机+数位DP
- BZOJ3530:[SDOI2014]数数——题解
- [bzoj3530][Sdoi2014]数数_AC自动机_数位dp
- BZOJ.3530.[SDOI2014]数数(AC自动机 数位DP)
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
- [BZOJ3530]-[Sdoi2014]数数-AC自动机+数位DP
- bzoj 3530: [Sdoi2014]数数
- bzoj 3530: [Sdoi2014]数数
- [BZOJ]3530 [SDOI2014] 数数 AC自动机 + DP
- 【BZOJ3530】数数(SDOI2014)-AC自动机+数位DP
- [BZOJ3530][SDOI2014]数数(AC自动机+数位dp)
- 【BZOJ】【3530】【SDOI2014】数数
- bzoj 3530: [Sdoi2014]数数 数位dp
- BZOJ 3530 【Sdoi2014】 数数