题意:
一个文本串A,一个模式串B,如果文本串含有模式串B,那么就能组合成多种意思,如下:
In the first case, “ hehehe” can have 3 meaings: “*he”, “he*”, “hehehe”.
In the third case, “hehehehe” can have 5 meaings: “*hehe”, “he*he”, “hehe*”, “**”, “hehehehe”.
题解:
多校的官方题解,我们队当时做也是这样的思路,不过我没用KMP,暴力匹配一样也才15ms,数据比较水
1001 Another Meaning
对于这个问题,显然可以进行DP:
令dp[i]表示到i结尾的字符串可以表示的不同含义数,那么考虑两种转移:
末尾不替换含义:dp[i - 1]
末尾替换含义:dp[i - |B|] (A.substr(i - |B| + 1,|B|) = B)
那么对于末尾替换含义的转移,需要快速判断BB能不能和当前位置的后缀匹配,kmp或者hash判断即可。
复杂度:O(N)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+7,mod=1e9+7; 4 char a[N],b[N]; 5 int dp[N]; 6 int main(){ 7 int t,ic=1; 8 scanf("%d",&t); 9 while(t--){ 10 scanf("%s%s",a+1,b+1); 11 int lena=strlen(a+1),lenb=strlen(b+1); 12 memset(dp,0,sizeof(dp)),dp[0]=1; 13 for(int i=1;i<=lena;i++){ 14 dp[i]=(dp[i]+dp[i-1])%mod; 15 int fg=0; 16 if(lena-i+1>=lenb)for(int j=1;j<=lenb;j++){ 17 if(a[i+j-1]!=b[j])break; 18 if(j==lenb)fg=1; 19 } 20 if(fg)dp[i+lenb-1]=(dp[i+lenb-1]+dp[i-1])%mod; 21 } 22 printf("Case #%d: %d ",ic++,dp[lena]); 23 } 24 return 0; 25 }