您的位置:首页 > 其它

HDU 5763(Another Meaning kmp+dp)

2016-07-29 16:28 405 查看
题目链接

有2个串,A,B,B有2个意思,问A串可以有几种表达的形式

dp[i]:表示以i结尾的种类数,如果A串从i-strlen(B)到i位置与B匹配,那么dp[i+1]=dp[i]+dp[i-strlen(B)],否则dp[i+1]=dp[i],用kmp记录匹配的结束位置。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#include<vector>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define LL long long
#define pb push_back
#define gcd __gcd

#define For(i,j,k) for(int i=(j);i<k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)

const int maxn = 2e5+200;
const LL inf  = 1LL << 34;
const LL mod = 1000000007;

int Next[maxn];
char a[maxn],b[maxn];

void getnext(char*s) {
int i=0,j=-1;
Next[0]=-1;
int len=strlen(s);
while(i<len) {
if(j==-1||s[i]==s[j])
Next[++i]=++j;
else
j=Next[j];
}
}

int x[maxn];
void kmp(char*p,char*s) {
int i=0,j=0;
int n=strlen(p);
int m=strlen(s);
while(i<n&&j<m) {
if(j==-1||p[i]==s[j])
i++,j++;
else
j=Next[j];
if(j==m) {
x[i-1]=1;
j=Next[j];
}
}
}
LL dp[maxn];
int main() {
int T;scanf("%d",&T);
int cas = 1;
while(T--) {
cl(dp,0);cl(x,0);
scanf("%s%s",b,a);
int len = strlen(a);
int N = strlen(b);
getnext(a);
kmp(b,a);
dp[0]=1;
for(int i=0;i<N;i++){
if(!x[i])dp[i+1]=dp[i];
else dp[i+1]=(dp[i]+dp[i+1-len])%mod;
}
printf("Case #%d: %lld\n",cas++,dp
%mod);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: