回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。每个字符串都可以通过向中间添加一些字符,使之变为回文字符串。
例如:abbc 添加2个字符可以变为 acbbca,也可以添加3个变为 abbcbba。方案1只需要添加2个字符,是所有方案中添加字符数量最少的。
Input
输入一个字符串Str,Str的长度 <= 1000。
Output
输出最少添加多少个字符可以使之变为回文字串。
Input示例
abbc
Output示例
2
作为蒟蒻的我看了这道题后并没有什么思路,再试水了几发后成功WA了,后来在聚聚们的暗中提示下终于大彻大悟
说一下思路:把原串A翻转过来作为B串,求出A,B的最长公共子序列,再用长度减去这个LCS就可以了
为什么呢,因为任何一个串,都可以变成回文串,最坏的情况就是整个复制下来是加在原串后,就是一个回文串了
只不过不确定是不是最短的,这时候你求出了LCS,只要在原串上加上不是LCS的那一部分字母,就会构成最短回文串了
下面贴上代码:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
string A,B,C;
int DP[1005][1005];
int main()
{
ios::sync_with_stdio(false); //加快读取速度
cin>>A;
C=A;
reverse(A.begin(),A.end());
B=A;
A=C; //A,B储存原串和翻转后的串
int len=A.size();
for(int i=1;i<=len;i++)
for(int j=1;j<=len;j++) //求LCS
{
if(A[i-1]==B[j-1])
{
DP[i][j]=DP[i-1][j-1]+1;
}
else if(DP[i-1][j]>DP[i][j-1])
{
DP[i][j]=DP[i-1][j];
}
else if(DP[i-1][j]<=DP[i][j-1])
{
DP[i][j]=DP[i][j-1];
}
}
cout<<len-DP[len][len]<<endl; //求出结果
return 0;
}