【luogu1435】回文字串

题目描述

回文词是一种对称的字符串。任意给定一个字符串,通过插入若干字符,都可以变成回文词。此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数。

比如 “Ab3bd”插入2个字符后可以变成回文词“dAb3bAd”或“Adb3bdA”,但是插入少于2个的字符无法变成回文词。

注:此问题区分大小写


输入

一个字符串(0<strlen<=5000)


输出

有且只有一个整数,即最少插入字符数


样例输入

Ab3bd


样例输出

2

 



题解

原串为s,s的倒序串为a,将s与a求一遍最长公共子序列,然后用s的长度减去最长公共子序列即可。

 

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

const int maxn=5000+50;

int n,dp[maxn][maxn];
char s[maxn],a[maxn];

template<typename T>void read(T& aa){
    char cc; ll ff;aa=0;cc=getchar();ff=1;
    while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
    if(cc=='-') ff=-1,cc=getchar();
    while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    aa*=ff;
}

int main(){
    cin>>s+1;
    n=strlen(s+1);
    for(int i=1;i<=n;i++)
    a[i]=s[n-i+1];
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    if(a[j]==s[i]) dp[i][j]=dp[i-1][j-1]+1;
    else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
    cout<<n-dp[n][n]<<endl;
    return 0;
}

 

posted @ 2018-09-04 15:57  rld  阅读(155)  评论(0编辑  收藏  举报