题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5763
题意:给我们一个母串a和模板串b,我们可以把母串里面包含的模板串换成另一个串,问我们最终可以得到多少种不同的串。
这题我们用到的思路就是KMP+DP。
首先,我们用KMP求解出所有的能够匹配模板串的位置,然后就可以开始DP求解了,状态转移方程为:
1.如果当前位置没有匹配到模板串,则dp[i] = dp[i-1];
2.如果当前位置匹配到了模板串,则dp[i] = dp[i-1] + dp[i-strlen(b)];
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100000+10;
const int MOD = 1e9+7;
char a[maxn], b[maxn];
int vis[maxn], nex[maxn], dp[maxn];
int n,m;
void getNext()
{
int j,k;
j = 0,k = -1;
nex[0] = -1;
while(j < m)
{
if(k == -1 || b[j] == b[k])
nex[++j] = ++k;
else k = nex[k];
}
}
void KMP()
{
int i=0, j=0;
getNext();
while(i<n)
{
if(j == -1 || a[i] == b[j])
i++, j++;
else j = nex[j];
if(j == m)
{
vis[i] = 1;
j = nex[j];
}
}
}
int main()
{
int T, t=1;
scanf("%d", &T);
while(T--)
{
scanf("%s%s", a, b);
n = strlen(a), m = strlen(b);
for(int i=0; i<=n; i++) vis[i] = 0, dp[i] = 0;
KMP();
dp[0] = 1;
for(int i=1; i<=n; i++)
{
dp[i] = dp[i-1] % MOD;
if(vis[i]) dp[i] = (dp[i] + dp[i-m]) % MOD;
}
printf("Case #%d: %d\n", t++, dp[n]);
}
}