题意:在一个字符串中插入一些字符,使字符串变成回文串,问插入的最小数量


...原来还有这种逆天公式

把这个字符串,和翻转后的字符串去算最长公共子序列,设为x

如果原长为L,那么答案就是L-x


滚动数组 poj1159 Palindrome_字符串仔细想想,还很有道理的样子....

因为,除了那部分公共子序列以外,只要把反序列的剩下的插入到正序里面去,就会形成回文串了。。


然后这题数据比较大,,但是好在求最长公共子序列可以用滚动数组解决

#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;
}