题解:P12837 [蓝桥杯 2025 国 B] 近似回文字符串
思路
令
于是答案即为
而
考虑如何计算
构造 1:如果字符串
构造 2:如果
但是两个构造中会出现重复统计的情况。
例如
再考虑到构造 2 中,如果左侧和右侧加入字母都能满足条件,那么便重复统计了,再减去即可。可以发现,这样的字符串只能是
于是递推得到
优化
可以化为
对于奇数项,
对于偶数项,
AC 代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
#define endl '\n'
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
int pw[N];
void Prework(const int n = N - 10) {
pw[0] = 1;
for (int i = 1;i <= n;i++) pw[i] = pw[i - 1] * 26 % MOD;
}
int baoli(int n) {
string s;
vector<string> a;
auto dfs = [&](auto&& dfs, int u) {
if (u == n + 1) {
string t = s;
reverse(t.begin(), t.end());
if (t == s) a.push_back(s);
// a.push_back(s);
return;
}
for (char i = 'a';i <= 'z';i++) {
s += i;
dfs(dfs, u + 1);
s.pop_back();
}
};
dfs(dfs, 1);
set<string> st;
int res = 0;
for (auto i : a) {
for (int j = 0;j < n;j++) {
string t = i.substr(0, j) + i.substr(j + 1);
string tt = t;
reverse(tt.begin(), tt.end());
if (tt == t) {
res += 1;
break;
}
}
}
return res;
}
void Solve() {
int n;cin >> n;
// cout << baoli(n) << endl;
vector<int> dp(n + 1);
dp[0] = 1;
dp[1] = 26;
for (int i = 2;i <= n;i++) {
int ans1 = dp[i - 2] * 26 % MOD;
int ans2 = pw[i / 2] * 25 * 2 % MOD;
int ans3 = i % 2 ? 0 : 25 * 26;
dp[i] = (ans1 + ans2 - ans3 + MOD) % MOD;
}
cout << (dp[n] - pw[(n + 1) / 2] + MOD) % MOD << endl;
// if (n & 1) {
// cout << pw[n / 2] * 50 * (n / 2) % MOD << endl;
// }
// else {
// cout << ((25 * n - 26) * pw[n / 2] % MOD + 26) % MOD;
// }
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T = 1;
// cin >> T;
Prework();
while (T--) Solve();
}