HihoCoder - 1807:好的数字串 (KMP DP)
Sample Input
6 1212
Sample Output
298
给定一个数字字符串S,如果一个数字字符串(只包含0-9,可以有前导0)中出现且只出现1次S,我们就称这个字符串是好的。
例如假设S=666,则1666、03660666是好的,6666、66、123不是好的;假设S=1212,则01212、12123是好的,121212、121是不好的。
请你计算长度为N的数字字符串中,有多少个是好的。由于总数可能很大,你只需要输出总数模1000000007的余数。
Input
一个整数N和一个数字串S。
对于30%的数据,1 ≤ N ≤ 8
对于100%的数据,1 ≤ N ≤ 1000,1 ≤ |S| ≤ N。
Output
一个整数代表答案。
思路:dp[i][j][k],表示前i位,而且当前尾巴与S的前缀的最长公共长度位j,k表示是否出现过S。 对于第i位,枚举0到9,并且用KMP找到最长公共部分。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const int Mod=1e9+;
int a[maxn],dp[maxn][maxn][],ans,N,L;
int Next[maxn]; char c[maxn];
void KMP()
{
for(int i=,k=;i<=L;i++){
while(k&&a[i]!=a[k+]) k=Next[k];
if(a[i]==a[k+]) k++; Next[i]=k;
}
}
int get(int i,int j)
{
while(){
if(a[i+]==j) return i+;
if(i==) break; i=Next[i];
}return ;
}
int main()
{
scanf("%d%s",&N,c+); L=strlen(c+); a[L+]=-;
rep(i,,L) a[i]=c[i]-''; dp[][][]=;
KMP();
rep(i,,N){
rep(j,,min(i-,L)){
rep(k,,) {
int t=get(j,k);
if(j==L-){
if(t==L) (dp[i][t][]+=dp[i-][j][])%=Mod;
else {
(dp[i][t][]+=dp[i-][j][])%=Mod;
(dp[i][t][]+=dp[i-][j][])%=Mod;
}
}
else {
if(t!=L) (dp[i][t][]+=dp[i-][j][])%=Mod;
(dp[i][t][]+=dp[i-][j][])%=Mod;
}
}
} }
rep(i,,L) (ans+=dp[N][i][])%=Mod;
printf("%d\n",ans);
return ;
}
HihoCoder - 1807:好的数字串 (KMP DP)的更多相关文章
- 【XSY2779】最小表示串 KMP DP polya定理
题目描述 给你一个字符串\(s\),问你有多少个串是最小表示串且字典序\(\leq s\) \(|s|\leq 1000\) 题解 先把\(s\)变成比\(s\)小的最大的最小表示串.方法是从后枚举每 ...
- hihocoder #1301 : 筑地市场 二分+数位dp
#1301 : 筑地市场 题目连接: http://hihocoder.com/problemset/problem/1301 Description 筑地市场是位于日本东京都中央区筑地的公营批发市场 ...
- 【模拟】Vijos P1005 超长数字串
题目链接: https://vijos.org/p/1005 题目大意: 无限的正整数按顺序拼接成字符串S(S=12345678910111213...),给你一个字符串A(len<=200)求 ...
- 洛谷P3193 [HNOI2008]GT考试 kmp+dp
正解:kmp+dp+矩阵优化 解题报告: 传送门! 啊刚说想做矩阵优化dp的字符串题就找到辣QwQ虽然不是AC自动机的但都差不多嘛QwQ 首先显然可以想到一个dp式?就f[i][j]:凑出i位了,在s ...
- BZOJ4037:[HAOI2015]数字串拆分——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4037 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时 ...
- bzoj4037 [HAOI2015]数字串拆分
Description 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导 ...
- ZZNU-oj-2141:2333--【O(N)求一个数字串能整除3的连续子串的个数,前缀和数组+对3取余组合数找规律】
2141: 2333 题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“ 宝儿姐考察你一道很简单的题目.给你一个数字串,你能判断有多少个连续子串能整除3吗? 输入 多实例输入,以E ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- HDU 6153 A Secret ( KMP&&DP || 拓展KMP )
题意 : 给出两个字符串,现在需要求一个和sum,考虑第二个字符串的所有后缀,每个后缀对于这个sum的贡献是这个后缀在第一个字符串出现的次数*后缀的长度,最后输出的答案应当是 sum % 1e9+7 ...
随机推荐
- Nodejs+mysql+Express: 一个简单的博客
推荐网址: https://github.com/nswbmw/N-blog/blob/backup/book/%E7%AC%AC1%E7%AB%A0%20%E4%B8%80%E4%B8%AA%E7% ...
- png文件格式详解,获取文件的修改时间,创作时间
http://dev.gameres.com/Program/Visual/Other/PNGFormat.htmhttp://www.360doc.com/content/11/0428/12/10 ...
- C#中使用SqlBulkCopy的批量插入和OracleBulkCopy的批量插入
1.首先我们做一下准备工作,在sql server和oracle分别建立一个Student表 oracle中 --创建Student表 -- create table Student( stuId n ...
- Linux第二周作业
通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 1.进入vi编写C语言程序代码,首先必须输入命令vi main,c,其中main.c是文件名. 紧接着按esc键退出编辑状态,再输入一个 ...
- learning ddr3 protocol
refercece: www.jedec.org https://www.cnblogs.com/zhongguo135/p/8486979.html :
- Asp.Net 中 HTTP 和 HTTPS 切换
Asp.Net 中 HTTP 和 HTTPS 切换 目的 HTTP,超文本传输协议,明文传输,无状态,服务器默认端口80 HTTPS,具有SSL加密的HTTP,加密传输,需要申请ca证书,服务器默 ...
- Linux运维工程师必学必备的8项IT技能
如果你在学习Linux,那么强烈推荐你选择RHEL和Centos作为学习的Linux发行版本,在公司及企业当中他们是使用最多的,毕竟学习除了本身是爱好,其次也是为了就业.Centos是RHEL的克隆版 ...
- 高效方便的IO库: System.IO.Pipelines
我们在编写网络程序的时候,经常会进行如下操作: 申请一个缓冲区 从数据源中读入数据至缓冲区 解析缓冲区的数据 重复第2步 表面上看来这是一个很常规而简单的操作,但实际使用过程中往往存在如下痛点: 数据 ...
- hdu3377
题解: 简单的插头dp 加上一个代价即可 代码: #include<cstdio> #include<cmath> #include<cstring> #inclu ...
- 【转】MySQL实现Oracle里的 rank()over(ORDER BY) 功能
Oracle rank()和dense_rank()的区别是: –rank()是跳跃排序,有两个第二名时接下来就是第四名 –dense_rank()l是连续排序,有两个第二名时仍然跟着第三名 sele ...