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

这一道题目洛谷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. 为什么不早点使用 Git...

    教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013739628770 ...

  2. 误删 EhCache 中的数据?

    最近遇到一个问题:在使用ehcache时,通过CacheManager.getCache(chachename).get(key),获取相应的缓存内对象(当时这个对象是个list), 有个同事写个方法 ...

  3. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  4. 从PRISM开始学WPF(一)WPF-更新至Prism7.1

    原文:从PRISM开始学WPF(一)WPF-更新至Prism7.1 我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的 ...

  5. WPF中的数据模板(DataTemplate)

    原文:WPF中的数据模板(DataTemplate) WPF中的数据模板(DataTemplate)                                                   ...

  6. LeetCode:9. Palindromic Number(Medium)

    原题链接:https://leetcode.com/problems/palindrome-number/description/ 1. 题目要求:判断一个int类型整数是否是回文,空间复杂度O(1) ...

  7. vi编辑图

    vi使用方法

  8. 转:C#微信公众号开发之接收事件推送与消息排重的方法

    本文实例讲述了C#微信公众号开发之接收事件推送与消息排重的方法.分享给大家供大家参考.具体分析如下: 微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这 ...

  9. PostgreSQL字段名和表名大小写的问题

    创建表的时候,表名和字段名必须全小写,然后查询的时候不管全大写或全小写,或是Camel模式都不会报错.只要名称中有大写字母,或者全大写,查询时就必须保证大小写正确并用双引号包起来,否则就会报“XXX不 ...

  10. mysql连接jdbc查询代码

    package com.answer.test; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.S ...