题意:给定本来回文的字符串,现在有些字母没了,问至少没了多少
思路
你怎么想不到呢白痴
最长回文子序列
子序列不一定连续
找到现有串中最长的回文子序列长度,给定串长 减去 最长回文子序列 就是没有回文的字母数,也就是最少脱落的字母数
区间DP
状态表示:此区间的最长回文子序列
状态计算:以区间端点在不在序列中作为分类依据
- 都在
- 只有一个在
- 都不在
分别得到 f[i+1][j-1] + 2
f[i+1][j] f[i][j-1] f[i+1][j-1]
其中 后三者有重叠,用前三者作做状态转移
实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int N = 1010;
int f[N][N];
string s;
int main()
{
cin >> s;
int n = s.size();
for(int len = 1; len <= n; len ++)
for(int i = 0; i + len - 1 < n; i ++)
{
int j = i + len - 1;
if(len == 1) f[i][j] = 1;
else
{
f[i][j] = max(f[i + 1][j], f[i][j - 1]);
//如果回文
if(s[i] == s[j])
{
f[i][j] = max(f[i][j], f[i + 1][j - 1] + 2);
}
}
}
cout << n - f[0][n - 1] << endl;
return 0;
}
与最长公共子序列有相似之处