[BZOJ3530]数数(AC自动机,动态规划) 题面 BZOJ 题解 很套路的\(AC\)自动机+\(DP\) 首先,如果长度小于\(N\) 就不存在任何限制 直接大力\(DP\) 然后强制限制不能走到带有标记的点上面 如果长度恰好为\(N\)的长度 那么,要考虑是否恰好卡在范围里面 于是\(DP\)状态多记一维 表示是否卡在范围里面 最后求一下和就行啦 #include<iostream> #include<cstdio> #include<cstdlib> #in…
3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 682  Solved: 364 Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运数.    给定N和S,计算不大于N的幸运数个数. Input 输入的第一行包含整数N.    接下来一行一个整数M,…
题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前数已经小于了\(N\),\(1\)表示当前数等于\(N\). Code #include<bits/stdc++.h> #define ll long long #define fo(i,x,y) for(int i=x;i<=y;i++) #define fd(i,x,y) for(int…
题目链接:BZOJ - 3530 题目分析 明显是 AC自动机+DP,外加数位统计. WZY 神犇出的良心省选题,然而去年我太弱..比现在还要弱得多.. 其实现在做这道题,我自己也没想出完整解法.. 就想出了个 O(l^3) 的做法: 完全按照数位统计的思想来,先统计长度不足 len 的数字的合法种类数,这个枚举开头,然后 AC 自动机 DP 一下,用 f[i][j] 表示到了第 i 位,在第 j 个节点上的合法数字个数.这样是 O(L^2). 然后长度等于 n 的部分,就按照数位统计,一位位向…
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1030 题意概括 给出n个模式串,问长度为m的串中有多少个至少含有这n个模式串中的任意一个. 注意,所有的串仅由A~Z 26个大写字母构成. 题解 AC自动机好题. 先构建一个AC自动机. 然后在AC自动机上面跑dp. 建议开滚动数组. dp[i][j]表示长度为i,在AC自动机上面走到了j的方案数. 每次把所有走到模式串尾的全动统计到答案并清零. 代码 #include <cstring> #…
[BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固定且完全随机的文章—— 也就是说,生成的文章中每个字节都是完全随机的.如果一篇文章中至少包含使用者们了解的一个单词,那么我们说这篇文章是可读的(我们称文章a包含单词b,当且仅当单词b是文章a的子串).但是,即使按照这样的标准,使用者现…
题目链接 题目大意:给定$n$个子串,要求构造一个长度为$m$的母串使得至少有一个子串是其子串.问方案数. ------------------------ 我们可以对要求进行转化:求出不合法的方案数,总方案数减去不合法的方案数即为合法方案数. 首先建一个AC自动机,对于每个串的末尾结点及其$fail$边指向的结点都打上标记,表示遍历AC自动机的时候不经过这些点(因为如果一个串是另一个串的后缀,显然这两个串都是合法的). 然后就可以大力DP了.设$f[i][j]$表示走了$i$步到达$j$结点的…
建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG的数据: 这组数据我觉得答案应该是1吧,无论如何组合'a'和'b'这两个字符,也无法得到模式串"ac"和"bd"!! AC代码 #include <stdio.h> #include <string.h> #include <queue&g…
传送门 默认大家都学过trie与AC自动机. 先求出fail,对于每个节点维护一个sum,sum[u]待表从根到u所形成的字符串能拿到几分.显然sum[u]=sum[fail] + (u是几个字符串的结尾). 设dp[i][j]代表长度为i到trie树上的j号节点所得的最大分数,显然有dp[i+1][j的字符k儿子] = max{dp[i+1][j的字符k儿子], dp[i][j] + sum[j的字符k儿子]} memset(dp, -, sizeof(dp)); dp[][] = ; ; i…
考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i位走到AC自动机上j节点的概率,枚举下个字符即可转移.同时记录此时期望伤害,找到合法串就统计入答案. 并且注意到每次转移是相同的.矩阵快速幂优化即可. 以及非常卡精度,需要全程long double.cout的保留小数位数误差是相当大的,必须用printf.并且转移到某个字符的概率即1/alphab…