bzoj3530: [Sdoi2014]数数
2017-02-08 18:05
246 查看
链接
http://www.lydsy.com/JudgeOnline/problem.php?id=3530题解
一个小错查了一下午,建trie图的时候我把0当做串的终止,可题目中明明要求0是合法的。。。唉。。
f[i][j]表示长度为i的数字匹配到j点的方案数(允许前导零没有大小限制),g[i][j]是有大小限制的。
然后直接dp就行了(ac自动机上的dp道路+数位dp套路)。
答案的统计:这个有点费脑子,枚举位数,枚举下一位从1~9,然后计入ans就行了。(其实不费脑子但是我今天有点智障)
代码
//AC自动机上的数位dp #include <cstdio> #include <algorithm> #include <queue> #include <cstring> #define maxn 2000 #define mod 1000000007 using namespace std; int num[maxn], trie[maxn][10], tail[maxn], tot=1, fail[maxn], N, f[maxn][maxn], g[maxn][maxn], h[maxn][maxn]; queue<int> q; void insert(int *s) { int p; for(p=1;*s!=-1 and !tail[p];s++)p=trie[p][*s]?trie[p][*s]:trie[p][*s]=++tot; tail[p]=1; } int acamove(int pos, int x) { for(;pos and !trie[pos][x];pos=fail[pos]); return pos?trie[pos][x]:1; } void acabuild() { int u, v, i; q.push(1); while(!q.empty()) { u=q.front();q.pop(); for(i=0;i<=9;i++) { if(trie[u][i]) { v=acamove(fail[u],i); fail[trie[u][i]]=v; q.push(trie[u][i]); } else trie[u][i]=acamove(u,i); } } } void input() { char s[maxn]; int t[maxn]; int M, i, j, l; scanf("%s%d",s,&M); N=strlen(s); for(i=0;i<N;i++)num[N-i]=s[i]-48; for(i=1;i<=M;i++) { scanf("%s",s); l=strlen(s); for(j=0;s[j];j++)t[j]=s[l-j-1]-48;t[l]=-1; insert(t); } } int dp() { int i, j, now, ans=0; f[0][1]=g[0][1]=1; for(i=0;i<N;i++) for(j=1;j<=tot;j++) { if(tail[j] or (!f[i][j] and !g[i][j]))continue; for(now=0;now<=9;now++) f[i+1][trie[j][now]]=(f[i+1][trie[j][now]]+f[i][j])%mod; for(now=0;now<=num[i+1];now++) { if(now!=num[i+1]) g[i+1][trie[j][now]]=(g[i+1][trie[j][now]]+f[i][j])%mod; else g[i+1][trie[j][now]]=(g[i+1][trie[j][now]]+g[i][j])%mod; } if(i<N-1) { for(now=1;now<=9;now++) if(!tail[trie[j][now]])ans=(ans+f[i][j])%mod; } else { for(now=1;now<=num ;now++) { if(tail[trie[j][now]])continue; if(now==num )ans=(ans+g[i][j])%mod; else ans=(ans+f[i][j])%mod; } } } return ans; } int main() { input(); acabuild(); printf("%d",dp()); return 0; }
相关文章推荐
- Bzoj3530: [Sdoi2014]数数
- Bzoj3530: [Sdoi2014]数数
- BZOJ3530: [Sdoi2014]数数
- bzoj3530【SDOI2014】数数
- bzoj3530 [Sdoi2014]数数
- 【AC自动机+数位DP】SDOI2014 数数
- bzoj 3530: [Sdoi2014]数数 数位dp
- 3530: [Sdoi2014]数数
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位DP)
- bzoj 3530: [Sdoi2014]数数
- bzoj 3530: [Sdoi2014]数数 (AC自动机+数位DP)
- [BZOJ3530][SDOI2014]数数
- [BZOJ3530] [Sdoi2014]数数 && AC自动机+dp
- bzoj3530 [Sdoi2014]数数(AC自动机+数位DP)
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
- 【BZOJ 3530】【SDOI 2014】数数
- Bzoj3530 [Sdoi2014]数数
- [bzoj3530][SDOI2014]数数
- bzoj 3530 [Sdoi2014]数数
- bzoj 3530: [Sdoi2014]数数