题意:在一个字符串中插入一些字符,使字符串变成回文串,问插入的最小数量
...原来还有这种逆天公式
把这个字符串,和翻转后的字符串去算最长公共子序列,设为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; }