Another Meaning (KMP + DP)

先用KMP重叠匹配求出各个匹配成功的尾串位置。然后利用DP去求,那转移方程应该是等于

  上一个状态                                        (无法匹配新尾巴)

  上一个状态 + 以本次匹配起点为结尾的状态(就是说有了新的位置) + 1 (单单一个新串)       (匹配成功)

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 7;
const int mod = 1000000007;
long long dp[maxn];
char str1[maxn], str2[maxn];
bool flag[maxn];
/*
* nex[] 的含义:x[i-nex[i]...i-1]=x[0...nex[i]-1]
* nex[i] 为满足 x[i-z...i-1]=x[0...z-1] 的最大 z 值(就是 x 的自身匹配)
*/
void kmp_pre(char x[], int m, int kmpNext[]) {
    int i, j;
    j = kmpNext[0] = - 1;
    i = 0;
    while(i < m) {
        while( - 1 != j && x[i] != x[j])
            j = kmpNext[j];
        kmpNext[++i] = ++j;
    }
}
/*
* kmpNext[i] 的意思:nex'[i]=nex[nex[...[nex[i]]]](直到
nex'[i]<0 或者 x[nex'[i]]!=x[i])
* 这样的预处理可以快一些
*/
void preKMP(char x[], int m, int kmpNext[]) {
    int i, j;
    j = kmpNext[0] = - 1;
    i = 0;
    while(i < m) {
        while( - 1 != j && x[i] != x[j])
            j = kmpNext[j];
        if(x[++i] == x[++j])
            kmpNext[i] = kmpNext[j];
        else
            kmpNext[i] = j;
    }
}
/*
* 返回 x 在 y 中出现的次数,可以重叠
*/
int nex[10010];
int KMP_Count(char x[], int m, char y[], int n) { //x 是模式串,y 是主串
    int i, j;
    int ans = 0;
//preKMP(x,m,nex);
    kmp_pre(x, m, nex);
    i = j = 0;
    while(i < n) {
        while( - 1 != j && y[i] != x[j])
            j = nex[j];
        i++;
        j++;
        if(j >= m) {
            ans++;
            flag[i] = 1;
            j = nex[j];
        }
    }
    return ans;
}
int main() {
    int T, ncase = 1;
    scanf("%d", &T);
    while(T --) {
        scanf("%s%s", str1, str2);
        int l1 = strlen(str1);
        int l2 = strlen(str2);
        memset(flag, 0, sizeof(flag));
        memset(dp, 0, sizeof(dp));
        KMP_Count(str2, l2, str1, l1);
        for(int i = l2; i <= l1; i ++)
            dp[i] = flag[i] ? (dp[i - 1] + dp[i - l2] + 1) % mod : dp[i - 1];
        printf("Case #%d: %lld
",ncase++,(dp[l1] + 1)%mod);
    }
    return 0;
}
more crazy more get!
原文地址:https://www.cnblogs.com/wethura/p/9832388.html