思路:
枚举中心点, 然后把字符串分为左右两个部分
然后跑最长公共子序列, 得到的最长公共子序列就是左右两边的字符串共同拥有的部分, 剩下的部分需靠操作添加
#include <iostream>
#include <algorithm>
#include <map>
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int result;
int main()
{
result = INT_MAX;
string s;
cin >> s;
for (int i = 1; i < s.size() - 1; i++) {
string left = s.substr(0, i);
string right = s.substr(i + 1, s.size());
reverse(right.begin(), right.end());
int len = max(left.size(), right.size());
int a[len + 1];
int b[len + 1];
int r[len + 1];
int c[len + 1];
map<int, int> mp;
int cnt = 0, pos = 0;
for (int i = 0; i < left.size(); i++) {
a[i + 1] = int(left[i]);
}
int xb = -1;
for (int i = left.size() + 1; i <= len; i++) {
a[i] = xb;
xb--;
}
for (int i = 0; i < right.size(); i++) {
b[i + 1] = int(right[i]);
}
for (int i = right.size() + 1; i <= len; i++) {
b[i] = xb;
xb--;
}
r[0] = 0;
for (int i = 1; i <= len; i++) {
mp[a[i]] = i;
r[i] = 0;
}
for (int i = 1; i <= len; i++) {
c[i] = mp[b[i]];
}
for (int i = 1; i <= len; i++)
{
if (a[i] < 0 or b[i] < 0) {
continue;
}
if (c[i] >= r[cnt])
{
r[++cnt] = c[i];
}
else
{
pos = lower_bound(r + 1, r + 1 + cnt, c[i]) - r;
r[pos] = c[i];
}
}
result = min(result, int(left.size() + right.size() - 2 * cnt));
}
for (int i = 1; i < s.size() - 2; i++) {
string left = s.substr(0, i);
string right = s.substr(i + 2, s.size());
reverse(right.begin(), right.end());
int len = max(left.size(), right.size());
int a[len + 1];
int b[len + 1];
int r[len + 1];
int c[len + 1];
map<int, int> mp;
int cnt = 0, pos = 0;
for (int i = 0; i < left.size(); i++) {
a[i + 1] = int(left[i]);
}
int xb = -1;
for (int i = left.size() + 1; i <= len; i++) {
a[i] = xb;
xb--;
}
for (int i = 0; i < right.size(); i++) {
b[i + 1] = int(right[i]);
}
for (int i = right.size() + 1; i <= len; i++) {
b[i] = xb;
xb--;
}
r[0] = 0;
for (int i = 1; i <= len; i++) {
mp[a[i]] = i;
r[i] = 0;
}
for (int i = 1; i <= len; i++) {
c[i] = mp[b[i]];
}
for (int i = 1; i <= len; i++)
{
if (a[i] < 0 or b[i] < 0) {
continue;
}
if (c[i] >= r[cnt])
{
r[++cnt] = c[i];
}
else
{
pos = lower_bound(r + 1, r + 1 + cnt, c[i]) - r;
r[pos] = c[i];
}
}
result = min(result, int(left.size() + right.size() - 2 * cnt));
}
cout << result << endl;
return 0;
}