DP × KMP
几道用到KMP的DP题:
hdu 5763 hdu 3689 hdu 3336 codeforces 494B codevs 3945
关于KMP的nx数组:
如果在本文中看见了nx[]指的是所谓“成功指针”,或者getnx()函数跟本人之前的板子写的不一样......
都是因为求nx数组有两种方法!!!
详情请阅本人的另一篇文章:关于KMP算法的重大发现
好了我们进入正题~
一道一道来~
hdu 5763 Another Meaning
题意及样例:原题链接
设第一个串为A,长为n;第二个串为B,长为L
从1到n计算1~k能代表的意思的数量f[k]
如果A[k-L+1,k]==B
则f[k]=f[k-L]+f[k-1]
否则f[k]=f[k-1]
判断A[k-L+1,k]是否与B匹配就要靠KMP了
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 1000000007
using namespace std; int t,al,bl;
char a[];
char b[];
int nx[];
int fl[];
int f[]; void getnx()
{
nx[]=;
for(int i=,j=;i<=bl;)
{
nx[i]=j;
while(j&&b[j]!=b[i])j=nx[j];
j++,i++;
}
} void kmp()
{
for(int i=,j=;i<=al;)
{
while(j&&b[j]!=a[i])j=nx[j];
if(j==bl)
{
fl[i]=;
j=nx[j];
}
else j++,i++;
}
} int main()
{
scanf("%d",&t);
for(int cs=;cs<=t;cs++)
{
memset(a,,sizeof(a));
memset(b,,sizeof(b));
memset(fl,,sizeof(fl));
scanf("%s",a+);
scanf("%s",b+);
al=strlen(a+);
bl=strlen(b+);
getnx();
kmp();
f[]=;
for(int i=;i<=al;i++)
{
if(fl[i])f[i]=(f[i-]+f[i-bl])%mod;
else f[i]=f[i-];
}
printf("Case #%d: %d\n",cs,f[al]);
}
return ;
}
hdu 5763 Another Meaning
hdu 3689 Infinite monkey theorem
概率DP,不一定一出错就要重头开始打。用nx[ ]数组转移,避免字符的浪费。
这里的nx[ ]数组指的是成功指针......(玄学)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n,m,len;
double p[];
char s[];
char key[];
int nx[];
double f[][]; void getnx()
{
nx[]=;
for(int i=,j=;i<=len;i++)
{
while(j&&s[i]!=s[j+])j=nx[j];
if(s[j+]==s[i])j++;
nx[i]=j;
}
} int main()
{
while(true)
{
memset(nx,,sizeof(nx));
for(int i=;i<=;i++)p[i]=0.00;
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
f[i][j]=0.00;
}
}
scanf("%d%d",&n,&m);
if(!n)return ;
for(int i=;i<=n;i++)
{
char c[];
scanf("%s",c+);
key[i]=c[];
scanf("%lf",&p[i]);
}
scanf("%s",s+);
len=strlen(s+);
getnx();
f[][]=1.00;
for(int i=;i<=m;i++)
{
for(int j=;j<len;j++)
{
for(int k=;k<=n;k++)
{
int ps=j;
while(ps&&s[ps+]!=key[k])ps=nx[ps];
if(s[ps+]==key[k])ps++;
f[i][ps]+=f[i-][j]*p[k];
}
}
}
double ans=0.00;
for(int i=;i<=m;i++)ans+=f[i][len];
printf("%.2lf%%\n",ans*100.00);
}
}
hdu 3689 Infinite monkey theorem
hdu 3336 Count the string
利用KMP中nx[ ]数组的性质。
上代码。
#include<cstdio>
#include<cstring>
using namespace std; int t,n,len,f[],ans;
char s[];
int nx[]; void getnx()
{
for(int i=;i<n;i++)
{
int j=nx[i];
while(j&&s[i]!=s[j]) j=nx[j];
nx[i+]= s[i]==s[j] ? j+:;
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%s",s);
len=strlen(s);
getnx();
memset(f,,sizeof(f));
ans=;
for(int i=;i<=n;i++)
{
f[i]=f[nx[i]]+;
ans+=f[i];
f[i]%=;
ans%=;
}
printf("%d\n",ans);
}
}
hdu 3336 Count the string
CodeForces 494B Obsessive String
比较复杂......
记录f[ ],f[ ]的前缀和s[ ],还有s[ ]的前缀和ss[ ] 。
KMP用来匹配字符串。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 1000000007
using namespace std; char a[],b[];
int al,bl;
int nx[];
int fl[];
int f[],s[],ss[]; void getnx()
{
nx[]=;
for(int i=,j=;i<=bl;)
{
nx[i]=j;
while(j&&b[j]!=b[i])j=nx[j];
i++,j++;
}
} void kmp()
{
for(int i=,j=;i<=al;)
{
while(j&&a[i]!=b[j])j=nx[j];
if(j==bl)fl[i]=,j=nx[j];
else i++,j++;
}
} int main()
{
scanf("%s",a+);
al=strlen(a+);
scanf("%s",b+);
bl=strlen(b+);
getnx();
kmp();
for(int i=;i<=al;i++)
{
if(fl[i])f[i]=(i-bl++ss[i-bl])%mod;
else f[i]=f[i-];
s[i]=(s[i-]+f[i])%mod;
ss[i]=(ss[i-]+s[i])%mod;
}
int ans=;
for(int i=;i<=al;i++)ans=(ans+f[i])%mod;
printf("%d",ans);
}
CodeForces 494B Obsessive String
CODEVS 3945 完美拓印
当成字符串匹配......
坑挺多的,各种方向都得匹配一次求出答案。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int a[],b[],s1[],s2[],nx[];
int n,m,ans; void getnx()
{
nx[]=nx[]=;
for(int i=;i<n;i++)
{
int j=nx[i];
while(j&&s1[i]!=s1[j])j=nx[j];
nx[i+]=(s1[i]==s1[j]?j+:);
}
} int kmp()
{
getnx();
int j=,cnt=;
for(int i=;i<m;i++)
{
while(j&&s2[i]!=s1[j])j=nx[j];
if(s2[i]==s1[j])j++;
if(j==n)cnt++,j=nx[j];
}
return cnt;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)scanf("%d",&a[i]);
for(int i=;i<m;i++)scanf("%d",&b[i]);
if(n==)
{
printf("%d\n",m<<);
return ;
}
n--; m--;
for(int i=;i<n;i++)s1[i]=a[i+]-a[i];
for(int i=;i<m;i++)s2[i]=b[i+]-b[i];
ans+=kmp();
for(int i=;i<n;i++)s1[i]=a[n-i]-a[n-i-];
ans+=kmp();
for(int i=;i<n;i++)s1[i]=;
ans+=*kmp();
printf("%d",ans);
return ;
}
CODEVS 3945 完美拓印
结束了。
最后顺便说,有些字符串匹配的题可以用hash做。
这样可以偷懒,不用写KMP
好吧还是乖乖背KMP板子吧。
溜了。
DP × KMP的更多相关文章
- BZOJ1009GT考试 DP + KMP + 矩陣快速冪
@[DP, KMP, 矩陣快速冪] Description 阿申准备报名参加GT考试,准考证号为\(N\)位数\(X_1 X_2 .. X_n(0 <= X_i <= 9)\),他不希望准 ...
- CF 346B. Lucky Common Subsequence(DP+KMP)
这题确实很棒..又是无想法..其实是AC自动机+DP的感觉,但是只有一个串,用kmp就行了. dp[i][j][k],k代表前缀为virus[k]的状态,len表示其他所有状态串,处理出Ac[len] ...
- bzoj 1009 [HNOI2008]GT考试(DP+KMP+矩阵乘法)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1009 [题意] 给定一个字符串T,问长度为n且不包含串T的字符串有多少种. [思路] ...
- hdu-3689 Infinite monkey theorem 概率dp+kmp
有一只猴子随机敲键盘,给出它可能敲的键以及敲各个键的概率. 输入:n,表示有多少个键,m,表示猴子会敲m次键 n个二元组(字母,数字) 表示键代表的字母及其被敲的概率. 最后一个目标字符串. 问这只猴 ...
- 4572: [Scoi2016]围棋 轮廓线DP KMP
国际惯例的题面:这种题目显然DP了,看到M这么小显然要状压.然后就是具体怎么DP的问题.首先我们可以暴力状压上一行状态,然后逐行转移.复杂度n*3^m+3^(m*2),显然过不去. 考虑状态的特殊性, ...
- 5.Longest Palindromic Substring (String; DP, KMP)
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- codeforces 825F F. String Compression dp+kmp找字符串的最小循环节
/** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...
- 【bzoj1009】[HNOI2008]GT考试(矩阵快速幂优化dp+kmp)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 这道题一看数据范围:$ n<=10^9 $,显然不是数学题就是矩乘快速幂优 ...
- HDU 5763 Another Meaning dp+字符串hash || DP+KMP
题意:给定一个句子str,和一个单词sub,这个单词sub可以翻译成两种不同的意思,问这个句子一共能翻译成多少种不能的意思 例如:str:hehehe sub:hehe 那么,有**he.he** ...
- HDU3689 Infinite monkey theorem 无限猴子(字符串DP+KMP)
题目描述: 大概的意思就是根据无限猴子定理,无限只猴子坐在打字机旁瞎敲,总有一个能敲出莎士比亚文集.现在给你一个打字机和一只猴子,打字机的每个按钮(共n个)上的字母及猴子按下这个按钮的概率已知,而且猴 ...
随机推荐
- C - Monitor CodeForces - 846D (二维前缀和 + 二分)
Recently Luba bought a monitor. Monitor is a rectangular matrix of size n × m. But then she started ...
- 小白学习之pytorch框架(2)-动手学深度学习(begin-random.shuffle()、torch.index_select()、nn.Module、nn.Sequential())
在这向大家推荐一本书-花书-动手学深度学习pytorch版,原书用的深度学习框架是MXNet,这个框架经过Gluon重新再封装,使用风格非常接近pytorch,但是由于pytorch越来越火,个人又比 ...
- Less(7)
1.先判断注入类型 (1)首先看到要求,要求传一个ID参数,并且要求是数字型的:?id=1 (2)再输入:?id=1 and 1=1 (3)输入:?id=1 and 1=2 因为(2)(3)没有变化, ...
- POJ-2031 Building a Space Station (球的最小生成树)
http://poj.org/problem?id=2031 Description You are a member of the space station engineering team, a ...
- 吴裕雄--天生自然 JAVA开发学习:抽象类
public abstract class Employee { private String name; private String address; private int number; pu ...
- 第04项目:淘淘商城(SpringMVC+Spring+Mybatis) 的学习实践总结【第四天】
https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...
- 一篇文章带你了解axios网络交互-Vue
来源:滁州SEO 1 **什么是axios呢?**了解,并去使用它,对于axios发送请求的两种方式有何了解,以及涉及axios跨域问题如何解决. 对于axios网络交互,去使用axios的同时,首先 ...
- matlab2016b
http://www.cnblogs.com/CQBZOIer-zyy/p/5933954.html
- D. Fish eating fruit
题:https://nanti.jisuanke.com/t/41403 题意:求任意俩点之间距离之和模3后的三个结果的总数(原距离之和) 第一种做法: 树形dp #include<bits/s ...
- 导入import的多种形式
参考资料:anaconda官方资料 一.module(模块) 比如fibo是个模块(.py文件),其中有fib.fib2等函数 第一种形式:import fibo 在当前的符号表中,这并不会直接进入到 ...