HDU 5763 Another Meaning 2016多校第四场1001 KMP+DP

题目链接: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;
}

posted on 2016-08-23 13:24  57老帅了  阅读(157)  评论(0编辑  收藏  举报

导航