回文串是指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; }