HDU5763 another meaning -(KMP+DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5763

思路:dp[i]表示前i个字符组成的字符串所表示的意思数量,则当匹配时dp[i]=dp[i-1]+dp[i-lenb],不匹配时dp[i]=dp[i-1]。匹配的判断可以用KMP。


#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+3;
const int mod=1e9+7;
char a[N],b[N];
ll dp[N];
int lena,lenb,next[N];
void get_next()
{
    int j = 0 ,k = -1;
    next[0] = -1;
    while(j < lenb)
    {
        if(k == -1 || b[j] == b[k])
        {
            j++,k++;
            next[j] = k;
        }
        else k = next[k];
    }
}
void kmp()
{
    get_next();
    int i = 0 ,j = 0;
    memset(dp,0,sizeof(dp));
    dp[0] = 1;
    while(i<lena)
    {
        if(j == -1||a[i]==b[j])
        {
            i++;
            dp[i] = dp[i-1];
            j++;
        }
        else j = next[j];
        if(j == lenb)
        {
            dp[i] = (dp[i-lenb] + dp[i]) % mod;
            j = next[j];
        }
    }
}
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s %s",a,b);
        lena=strlen(a),lenb=strlen(b);
        kmp();
        printf("Case #%d: %lld
",cas++,dp[lena]);
    }
    return 0;
}