bzoj3530: [Sdoi2014]数数
来源:互联网 发布:摩拜魔方大数据未来 编辑:程序博客网 时间:2024/05/24 05:28
链接
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 1000000007using 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[N];now++) { if(tail[trie[j][now]])continue; if(now==num[N])ans=(ans+g[i][j])%mod; else ans=(ans+f[i][j])%mod; } } } return ans;}int main(){ input(); acabuild(); printf("%d",dp()); return 0;}
0 0
- [bzoj3530][SDOI2014]数数
- bzoj3530【SDOI2014】数数
- bzoj3530: [Sdoi2014]数数
- BZOJ3530 [SDOI2014]数数
- [BZOJ3530] [Sdoi2014]数数 && AC自动机+dp
- 【bzoj3530】【sdoi2014】【数数】【AC自动机+数位dp】
- [BZOJ3530]-[Sdoi2014]数数-AC自动机+数位DP
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位dp)
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位DP)
- bzoj3530 [Sdoi2014]数数(AC自动机+数位DP)
- [SDOI2014]数数
- 【SDOI2014】数数
- 【SDOI2014】数数
- 【BZOJ 3530】 [Sdoi2014]数数
- [SDOI2014][JZOJ3624]数数
- BZOJ 3530 【Sdoi2014】 数数
- 3530: [Sdoi2014]数数
- bzoj 3530 [Sdoi2014]数数
- eclipse tomcat add and remove工程异常
- thinkphp+redis+队列
- 优酷视频播放器去广告服务
- 简述Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method)
- Nginx安装部署
- bzoj3530: [Sdoi2014]数数
- u3d网格编程-绘制多面片长方体
- Understand Webpack part 2
- layer 的使用
- Java微信公众号开发(待续)
- 帧布局管理器与相对布局管理器的常用属性(自用)
- 深入浅出异步I/O模型
- android中的xml布局元素和属性
- logback 日志分离技术