题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5763
题意:给你两个字符串A,B。找出A中可以表达多少种B的含义,如A=hehehe,B=hehe,A有三种含义: “()he”, “he()”, “hehehe”。A可以表达B或者不表达B(也就是题目中B有两种含义)。
题解:裸的kmp模板题,加上一个dp即可。
令dp[i]表示到i结尾的字符串可以表示的不同含义数,那么考虑两种转移:
末尾不替换含义:dp[i - 1]
末尾替换含义:dp[i - |B|] (A.substr(i - |B| + 1,|B|) = B)
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int T;
char s[100005];
char ss[100005];
int jump[100050];
int dp[100005];
int main()
{
scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
scanf("%s\n%s",s+1,ss+1);
//cout<<s<<" "<<ss<<endl;
int n=strlen(s+1),m=strlen(ss+1);
jump[0]=1,jump[1]=1;
for(int i=2;i<=m;i++)
{
int j=jump[i];
while(j!=1&&ss[i]!=ss[j]) j=jump[j];
jump[i+1]=ss[i]==ss[j]?j+1:0;
}
int j=1;
dp[0]=1;
for(int i=1;i<=n;i++)
{
while(j!=1&&ss[j]!=s[i]) j=jump[j];
if(ss[j]==s[i]) j++;
dp[i]=dp[i-1];
if(j==m+1)
dp[i]=(dp[i]+dp[i-m])%mod;
}
printf("Case #%d: %d\n",kase,dp[n]);
}
return 0;
}