题意:在一个字符串中插入一些字符,使字符串变成回文串,问插入的最小数量
...原来还有这种逆天公式
把这个字符串,和翻转后的字符串去算最长公共子序列,设为x
如果原长为L,那么答案就是L-x
仔细想想,还很有道理的样子....
因为,除了那部分公共子序列以外,只要把反序列的剩下的插入到正序里面去,就会形成回文串了。。
然后这题数据比较大,,但是好在求最长公共子序列可以用滚动数组解决
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MX = 5500 + 5;
const int INF = 0x3f3f3f3f;
char S1[MX], S2[MX];
int dp[2][MX];
int main() {
int L;
while(~scanf("%d%s", &L, S1 + 1)) {
for(int i = 1; i <= L; i++) {
S2[i] = S1[L - i + 1];
}
int cur = 0, nxt = 1;
for(int i = 1; i <= L; i++) {
memset(dp[nxt], 0, sizeof(dp[nxt]));
for(int j = 1; j <= L; j++) {
if(S1[i] == S2[j]) {
dp[nxt][j] = dp[cur][j - 1] + 1;
} else {
dp[nxt][j] = max(dp[nxt][j - 1], dp[cur][j]);
}
}
swap(cur, nxt);
}
printf("%d\n", L - dp[cur][L]);
}
return 0;
}