真的很开心呢,总算是有一道完完全全由自己做出来的题目啦~

这一道题目洛谷P3311和另一道JSOI文本生成器的题目是十分相像的,dp方面几乎相同。只是<=n的约束,让这道题目必须结合数位dp的方法,新建一个维度代表之后数字的大小是否受到限制。0代表受限,1代表不受限。但是处理前导零的部分的确较为头痛,最后采取的方法是在第一次dp的时候不允许有前导零的存在,在第二次dp的时候才把这一部分的答案统计出来。所以在第二次的dp转移中,一个节点只能由父亲节点、而不能由Fail节点转移而来。

#include <bits/stdc++.h>
using namespace std;
#define maxn 2000
#define mod 1000000007
int m, cnt = , len, ans, ch[maxn][], dp[maxn][maxn][], fail[maxn];
bool error[maxn];
string n, s;
struct AC_Automation
{
void Trie_ins()
{
int now = , len = s.length();
for(int i = ; i < len; i ++)
{
if(!ch[now][s[i] - '']) ch[now][s[i] - ''] = ++ cnt;
now = ch[now][s[i] - ''];
}
error[now] = true;
} void AC_build()
{
queue <int> q;
q.push();
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = ; i < ; i ++)
{
if(ch[u][i])
{
int v = ch[u][i], k = fail[u];
while(!ch[k][i]) k = fail[k];
fail[v] = ch[k][i];
if(error[fail[v]]) error[v] = true;
q.push(v);
}
else ch[u][i] = ch[fail[u]][i];
}
}
}
}ACM; void DP(int x)
{
for(int i = ; i <= cnt; i ++)
{
if(error[i] || (!dp[x - ][i][] && !dp[x - ][i][])) continue;
for(int j = ; j < ; j ++)
{
if(x == && j == ) continue;
int k = i;
while(!ch[k][j]) k = fail[k];
int v = ch[k][j];
if(j == n[x - ] - '') dp[x][v][] = (dp[x][v][] + dp[x - ][i][]) % mod;
if(j < n[x - ] - '') dp[x][v][] = (dp[x][v][] + dp[x - ][i][]) % mod;
dp[x][v][] = (dp[x][v][] + dp[x - ][i][]) % mod;
}
}
} void DP2()
{
dp[][][] = ;
for(int x = ; x < len; x ++)
for(int i = ; i <= cnt; i ++)
{
if(error[i] || !dp[x - ][i][]) continue;
for(int j = ; j < ; j ++)
{
if(x == && j == ) continue;
int k = i;
int v = ch[k][j];
dp[x][v][] = (dp[x][v][] + dp[x - ][i][]) % mod;
}
}
for(int i = ; i < len; i ++)
for(int j = ; j <= cnt; j ++)
if(!error[j]) ans = (ans + dp[i][j][]) % mod;
} int main()
{
cin >> n;
cin >> m;
for(int i = ; i < ; i ++) ch[][i] = ;
for(int i = ; i <= m; i ++)
{
cin >> s;
ACM.Trie_ins();
}
ACM.AC_build();
len = n.length();
dp[][][] = ;
for(int i = ; i <= len; i ++) DP(i);
for(int i = ; i <= cnt; i ++)
if(!error[i]) ans = (ans + dp[len][i][] + dp[len][i][]) % mod;
memset(dp, , sizeof(dp));
DP2();
printf("%d\n", ans);
return ;
}

【题解】SDOI2014数数的更多相关文章

  1. 题解-[SDOI2014]数数

    [SDOI2014]数数 这题的前置知识是AC自动机和dp,前置题目是 [JSOI2007]文本生成器,前置题目我写的题解 题解-[JSOI2007]文本生成器.我的讲解假设你做过上面那道题. 这题比 ...

  2. BZOJ3530: [Sdoi2014]数数

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 322  Solved: 188[Submit][Status] ...

  3. 【BZOJ】【3530】【SDOI2014】数数

    AC自动机/数位DP orz zyf 好题啊= =同时加深了我对AC自动机(这个应该可以叫Trie图了吧……出边补全!)和数位DP的理解……不过不能自己写出来还真是弱…… /************* ...

  4. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 682  Solved: 364 Description 我们称一 ...

  5. BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]

    3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...

  6. 「SDOI2014」数数 解题报告

    「SDOI2014」数数 题目描述 我们称一个正整数 \(N\) 是幸运数,当且仅当它的十进制表示中不包含数字串集合 \(S\) 中任意一个元素作为其子串. 例如当 \(S=(\)22, 333, 0 ...

  7. 3530: [Sdoi2014]数数

    3530: [Sdoi2014]数数 链接 分析: 对给定的串建立AC自动机,然后数位dp.数位dp的过程中,记录当前在AC自动机的哪个点上,保证不能走到出现了给定串的点. 代码: #include& ...

  8. [SDOI2014]数数 --- AC自动机 + 数位DP

    [SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...

  9. bzoj [Sdoi2014]数数 AC自动机上dp

    [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1264  Solved: 636[Submit][Status][Discu ...

  10. [Sdoi2014]数数[数位dp+AC自动机]

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 834  Solved: 434[Submit][Status][ ...

随机推荐

  1. 【shell脚本学习-3】

    part-1 #!/bin/bash:<<FTP#test [ 1 -eq 2] #条件测试x="abc" #不允许有空格y="abc" [ &qu ...

  2. ruby 数据类型Range

    范围(Range)无处不在:a 到 z. 0 到 9.等等.Ruby 支持范围,并允许我们以不同的方式使用范围: 作为序列的范围 作为条件的范围 作为间隔的范围 作为序列的范围 (1..5) #==& ...

  3. 网站title标题被改并被百度网址安全中心提醒的解决办法

    国庆假日期间我们Sine安全接到众多网站站长求助网站标题被改导致在百度搜索中百度安全中心提醒被拦截,导致网站正常用户无法浏览网站被跳转到一些菠菜du博网站,而且很明显的一个特征就是在百度中搜索关键词的 ...

  4. (数据科学学习手札24)逻辑回归分类器原理详解&Python与R实现

    一.简介 逻辑回归(Logistic Regression),与它的名字恰恰相反,它是一个分类器而非回归方法,在一些文献里它也被称为logit回归.最大熵分类器(MaxEnt).对数线性分类器等:我们 ...

  5. Spark 实践

    1.1 避免使用 GroupByKey   让我们看一下使用两种不同的方式去计算单词的个数,第一种方式使用 reduceByKey, 另外一种方式使用 groupByKey: val words = ...

  6. poj1050 dp动态规划

    Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...

  7. BZ 600题祭

    不知不觉就600题了呢. 明天就要省选了.不要让这个数字定格在这里吧!

  8. 1321. [ZJOI2012] 灾难

    1321. [ZJOI2012] 灾难 ★★☆   输入文件:catas.in   输出文件:catas.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 阿米巴是小强的 ...

  9. Linux - 信息收集

    1. #!,代表加载器(解释器)的路径,如: #!/bin/bash echo "Hello Boy!" 上面的意思是说,把下面的字符(#!/bin/bash以下的所有字符)统统传 ...

  10. 部署:阿里云ECS部署Docker CE

    1 部署阿里云ECS,选择CentOS操作系统,并启动实例: 2 部署Docker CE: a.检查centos版本: $ cat /etc/redhat-release CentOS Linux r ...