转移的时候要注意对于S[0--i]后缀的最长匹配 如果最长匹配为整个T串,那么就可以开始转移,转移时新出现的T可以从上一个完整的T的公共前缀的next转移加1过来,这就相当于用上一个T中的后缀作为当前T的前缀,不断求NEXT求出一个最大的转移,不断执行。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int Next[maxn];
int dp[maxn];
char s[maxn],t[maxn];
int cnt[maxn];
void getNext(char str[],int len)
{
int j, i = 0;
Next[0] = j = -1;
while(i < len)
{
while(j != -1 && str[i] != str[j]) j = Next[j];
Next[++i] = ++j;
}
}
int main()
{
cin >> s >> t;
getNext(t,strlen(t));
int len_t = strlen(t);
int len_s = strlen(s);
for(int i = len_t-1 ; i < len_s ; i ++)
{
bool flag = true;
for(int j = 0 ; j < len_t ; j++)
{
if(s[i-j] != '?' && s[i-j] != t[len_t - 1 - j])
{
flag = false;
break;
}
}
dp[i] = dp[i-1];
if(flag)
{
cnt[i] = dp[i-len_t];
for(int j = Next[len_t] ; j != -1 ; j = Next[j])
{
cnt[i] = max(cnt[i], cnt[i-len_t+j]);
}
cnt[i]++;
dp[i] = max(dp[i], cnt[i]);
}
// cout << i << "-" << cnt[i] << endl;
}
cout << dp[len_s-1] << endl;
return 0;
}