Acwing设计密码
题意:
有字符串S,要求:
- 长度是n
- 仅包含小写字母
- 不包含子串T(这里的字串必须是连续才算)
求S的个数
n<=50,|T|<=50;
解法:
分为m+1个状态,从0到m,分别表示了当前的S的长度中的next[j]的值
即f[i] [j]表示了在字串长度是i时,最后一个字符所能匹配到的T中最大的下标(就是next的定义)
根据当前字符的取值转移到f[i+1] [x]的状态
复杂度:
n * m * 26 * n
#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
#define LL long long
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 55,mod=1e9+7;
int n, m;
int f[N][N];
int ne[N];
string str;
int main() {
cin >> n;
cin >> str;
m = str.size();
str = " " + str;
f[0][0] = 1;
for (int i = 2, j = 0; i <= m; i++) {
while (j&&str[i] != str[j + 1])j = ne[j];
if (str[i] == str[j + 1])j++;
ne[i] = j;
}
for(int i=0;i<n;i++)
for(int j=0;j<=m;j++)
for (char z = 'a'; z <= 'z'; z++) {
int u = j;
while (u&&str[u + 1] != z)u = ne[u];
if (str[u + 1] == z)u++;
if (u != m)f[i + 1][u] = (f[i + 1][u] + f[i][j]) % mod;
}
int res = 0;
for (int i = 0; i < m; i++)res = (res + f[n][i]) % mod;
cout << res << endl;
}
浙公网安备 33010602011771号