数数 bzoj-3530 Sdoi-2014

题目大意:给你一个整数集合,求所有不超过n的正整数,是的它的十进制表示下不能再一段等于集合中的任意数。

注释:$1\le n \le 1200$,$1\le |S|\le 100$,$1\le L\le 1500$,L是总长度之和。

想法:咳咳,显然,我们... ...什么都不想,看着能开下先把AC自动机扔出来

然后,其实数位dp就可以了

具体看代码

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define mod 1000000007
using namespace std;
typedef long long ll;
struct tree
{
int fail;
int vis[11];
int end;
}a[1600];
char s[1600],t[1250];
int n,m,cnt;
ll f[3][1250][1600],ans;
void build(char *s)
{
int l=strlen(s);
int now=0;
for(int i=0;i<l;i++)
{
int x=s[i]-'0';
if(!a[now].vis[x])
{
a[now].vis[x]=++cnt;
}
now=a[now].vis[x];
}
a[now].end|=1;
}
queue<int>q;
void getfail()
{
while(!q.empty()) q.pop();
for(int i=0;i<10;i++)
{
if(a[0].vis[i]!=0)
{
a[a[0].vis[i]].fail=0;
q.push(a[0].vis[i]);
}
}
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=0;i<10;i++)
{
if(!a[now].vis[i])
{
a[now].vis[i]=a[a[now].fail].vis[i];
}
else
{
a[a[now].vis[i]].fail=a[a[now].fail].vis[i];
a[a[now].vis[i]].end|=a[a[a[now].fail].vis[i]].end;
q.push(a[now].vis[i]);
}
}
}
}
int main()
{
scanf("%s",t+1);
m=strlen(t+1);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%s",s),build(s);
getfail();
for(int i=0;i<m;i++)
{
for(int j=0;j<=cnt;j++)
{
if(!j)
{
if(!i)
{
int x=t[i+1]-'0';
for(int k=1;k<x;k++)
{
if(!a[a[j].vis[k]].end)
{
f[1][i+1][a[j].vis[k]]+=1;
f[1][i+1][a[j].vis[k]]%=mod;
}
}
if(!a[a[j].vis[x]].end)
{
f[0][i+1][a[j].vis[x]]+=1;
f[0][i+1][a[j].vis[x]]%=mod;
}
}
else
{
for(int k=1;k<=9;k++)
{
if(!a[a[j].vis[k]].end)
{
f[1][i+1][a[j].vis[k]]++;
f[1][i+1][a[j].vis[k]]%=mod;
}
}
}
}
if(f[0][i][j])
{
int x=t[i+1]-'0';
for(int k=0;k<x;k++)
{
if(!a[a[j].vis[k]].end)
{
f[1][i+1][a[j].vis[k]]+=f[0][i][j];
f[1][i+1][a[j].vis[k]]%=mod;
}
}
if(!a[a[j].vis[x]].end)
{
f[0][i+1][a[j].vis[x]]+=f[0][i][j];
f[0][i+1][a[j].vis[x]]%=mod;
}
}
if(f[1][i][j])
{
for(int k=0;k<=9;k++)
{
if(!a[a[j].vis[k]].end)
{
f[1][i+1][a[j].vis[k]]+=f[1][i][j];
f[1][i+1][a[j].vis[k]]%=mod;
}
}
}
}
}
for(int i=0;i<=cnt;i++)
{
ans+=f[0][m][i];
ans%=mod;
ans+=f[1][m][i];
ans%=mod;
}
printf("%lld\n",ans);
return 0;
}

小结:我们在处理字符串问题的时候脑子里先有几个数据结构在搞事情.. ...

最新文章

  1. 《JS实现复制内容到剪贴板功能,可兼容所有PC浏览器,不兼容手机端》
  2. nodejs安装express不是内部或外部命令
  3. 区块 Blocks
  4. Ubuntu 14 常用“快捷键”,Ctrl + Alt + F1 进入终端,按 Ctrl + Alt + F7 回到界面
  5. Hibernate中延迟加载和缓存
  6. FileInputstream的available()方法
  7. CentOS 7.0安装MPlayer
  8. Leetcode#79 Word Search
  9. Drawable(4)LevelListDrawable
  10. 设计模式——设计模式之禅day1
  11. (二)list或set的遍历
  12. Android开发UI之android:gravity / android:layout_Gravity,android:padding / android:layout_margin属性区分
  13. MongoDB 任意代码执行漏洞(CVE-2013-4142)
  14. Java 多态 父类和子类方法的访问控制权限
  15. ajaxpro——js调用后台的方法
  16. XBee模块户外通信距离测试
  17. leetcode — permutation-sequence
  18. 如何解决OpenStack创建虚拟机或删除虚拟机时一直处于deleting或者creating状态的问题(转载)
  19. what&#39;s the 跨期套利
  20. Material Design Support 8大控件介绍

热门文章

  1. 实现泛型IEnumerable接口
  2. Java项目打包发布
  3. bzoj1705[Usaco2007 Nov]Telephone Wire 架设电话线(dp优化)
  4. 【寒假集训系列DAY.1】
  5. 【Codeforces】Codeforces Round #373 (Div. 2)
  6. java 实现将java对象转为yaml文件
  7. VS2015 右侧导航插件地址
  8. C#之纯数字判断
  9. 基于mybatis向oracle中插入数据的性能对比
  10. uva11205 The broken pedometer 子集生成