51nod 1092 回文字符串

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

猜你喜欢

转载自blog.csdn.net/Whyckck/article/details/80279645