题目描述
回文词是一种对称的字符串。任意给定一个字符串,通过插入若干字符,都可以变成回文词。此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数。
比如 “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; }