[POJ 1159] Palindrome
http://poj.org/problem?id=1159
题意:
给你一个字符串,问你至少要插入多少个字符使之成为回文串。
思路:
对于一个回文串来说,其左右两边对应的字符是一样的,所以一个回文串的正串与反串的LCS应该等于回文串的长度。接下来我们考虑普通的字符串,其左右两边对应的字符不一定相同,但我们在统计其正反串的LCS时,可以找到去掉一些字符后,该字符串可以形成的最长的回文串。因此,我们只需要在对应位置插入字符串,就能让其变成回文串,所以答案为原字符串长度 - 正反串LCS的长度。
另外直接开长度为5e3的二维dp数组会MLE。对于LCS而言,我们枚举第一个字符时,其状态只能从上一个字符转移而来,所以可以采用滚动数组的方式来降低空间复杂度。
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 5e3 + 7;
char a[N];
int dp[2][N], n;
void solve() {
int now = 1;
for (int i = 0; i < n; ++i) {
for (int j = n - 1; j >= 0; --j) {
dp[now][j] = max(dp[now^1][j], dp[now][j + 1]);
if (a[i] == a[j]) dp[now][j] = max(dp[now ^ 1][j + 1] + 1, dp[now][j]);
}
now ^= 1;
}
printf("%d\n", n - dp[now ^ 1][0]);
}
int main() {
scanf("%d", &n);
scanf("%s", a);
solve();
return 0;
}

浙公网安备 33010602011771号