题解 AT693 【文字列】
Description
构造一个小写字母构成的字符串,使小写字母
- 没有两个合法位置或不合法位置是相邻的。
- 每一个合法位置可以插入任意个字母,也可以不插。
可以想到状态,令 bbbccddddeeefgg 中 bbb 是第一段,于是
枚举
考虑一个问题:将所有小写字母
减少的就是
所以,
转移方程如下,其中
时间复杂度
Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 500 + 5, p = 1e9 + 7;
inline int read() {
int X = 0,w = 0; char ch = 0;
while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar();
return w ? -X : X;
}
int f[26][N], C[N][N], freq[N], sum, fir, n;
signed main() {
for (int i = 0; i < 26; i++) {
freq[n] = read();
if (freq[n]) n++;
}
for (int i = 0; i <= 300; i++) {
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % p;
}
f[0][freq[0] - 1] = 1, sum = freq[0];
for (int i = 1; i < n; i++) {
for (int k = 0; k <= sum; k++)
for (int bad = 0; bad <= min(freq[i], k); bad++)
for (int good = 0; good + bad <= freq[i] && good <= sum + 1 - k; good++) {
int j = k - bad + freq[i] - good - bad;
f[i][j] = (f[i][j] + f[i - 1][k] * C[k][bad] % p * C[sum + 1 - k][good] % p
* C[freq[i] - 1][good + bad - 1] % p) % p;
}
sum += freq[i];
}
printf("%lld\n", f[n - 1][0]);
return 0;
}