自古字符串题目,不是后缀就是dp......
f[i][j]表示匹配到第i个串,已经匹配到了主串的第j位时的方案数。
初值:f[0][x] = 0 (x∈[0, 10000])
用哈希去判是否能更新。如果保险起见可以用KMP(单模式串匹配问题)。
#include <cstdio>
#include <cstring>
#define mod 1000000007
char s[10010], a[10010]; int k, n, m, f[110][10010]; unsigned long long hash1[10010], bin[10010];
inline unsigned long long gethash1(int l, int r) {return hash1[r] - hash1[l - 1] * bin[r - l + 1];}
int main() {
bin[0] = 1; for(int i = 1; i <= 10000; ++i) bin[i] = bin[i - 1] * 13331;
scanf("%d%s", &k, s+1); n = strlen(s+1);
for(int i = 1; i <= n; ++i) hash1[i] = hash1[i - 1] * 13331 + s[i];
memset(f, 0, sizeof(f)); for(int i = 0; i <= 10000; ++i) f[0][i] = 1;
for(int i = 1; i <= k; ++i) {
int num; scanf("%d", &num);
for(int ii = 1; ii <= num; ++ii) {
scanf("%s", a+1); m = strlen(a+1); unsigned long long hash = 0;
for(int j = 1; j <= m; ++j) hash = hash * 13331 + a[j];
for(int j = 0; j <= n - m; ++j)
if(hash == gethash1(j + 1, j + m)) f[i][j + m] = (f[i][j + m] + f[i - 1][j]) % mod;
}
}
int ans = 0;
for(int i = 0; i <= n; ++i) ans = (ans + f[k][i]) % mod; printf("%d", ans);
return 0;
}