P3311 数数

1|0P3311 数数

题意:

我们称一个正整数 x 是幸运数,当且仅当它的十进制表示中不包含数字串集合 s 中任意一个元素作为其子串。例如当 s={22,333,0233}时,233是幸运数,2333202333223 不是幸运数。给定 ns,计算不大于 n的幸运数个数。

答案对 109+7 取模。

思路:

数位dp + AC自动机

实现:

#include <stdio.h> #include <algorithm> #include <vector> #include <cstring> using namespace std; const int N = 1505, mod = 1e9 + 7; int idx = 1, tr[N][12], cnt[N], q[N], nex[N]; //首位是k,到第i位,匹配到j long long f[N][N][2][2]; char s[N]; char num[N]; int m; void insert() { int p = 0; for (int i = 1; s[i]; i++) { int t = s[i] - '0'; if (!tr[p][t]) tr[p][t] = idx++; p = tr[p][t]; } cnt[p] = 1; } void build() { int hh = 1, tt = 0; for (int i = 0; i <= 9; i++) if (tr[0][i]) q[++tt] = tr[0][i]; while (hh <= tt) { int t = q[hh++]; for (int i = 0; i <= 9; i++) { int &p = tr[t][i]; if (!p) p = tr[nex[t]][i]; else { nex[p] = tr[nex[t]][i]; q[++tt] = p; cnt[p] |= cnt[nex[p]]; } } } } // pos:当前处理第几位,trie_pos当前的状态,limit当前是否被限制,lead是否有前导0 int dfs(int pos, int trie_pos, bool limit, bool lead) { if (!pos) return !cnt[trie_pos]; if (cnt[trie_pos]) return 0; if (!limit && !lead && f[pos][trie_pos][limit][lead] != -1) return f[pos][trie_pos][limit][lead]; int up = limit ? (num[pos] - '0') : 9, res = 0; for (int i = 0; i <= up; i++) // 处理下一位 如果填0并且有前导0 前面顶了上限并且当前也顶上限下一位就会被限制 前面有前导0,或当前位0 res = ((int)res + dfs(pos - 1, (lead & !i) ? 0 : tr[trie_pos][i], limit & (i == up), lead & !i)) % mod; //记忆化 f[pos][trie_pos][limit][lead] = res; return res; } int main() { scanf("%s%d", num + 1, &m); for (int i = 1; i <= m; i++) { scanf("%s", s + 1); insert(); } build(); int len = strlen(num + 1); reverse(num + 1, num + len + 1); memset(f, -1, sizeof f); printf("%d\n", dfs(len, 0, 1, 1) - 1); return 0; }

__EOF__

本文作者zxr
本文链接https://www.cnblogs.com/zxr000/p/16559553.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zxr000  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示