hdu_5763_Another Meaning(dp)

题目链接:hdu_5763_Another Meaning

题意:

一个文本串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\n",ic++,dp[lena]);
23     }
24     return 0;
25 }
View Code

 

posted @ 2016-07-28 18:50  bin_gege  阅读(308)  评论(0编辑  收藏  举报