Description
As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.
Input
Output
Sample Input
5
Ab3bd
Sample Output
2
题目大意:给出一个字符串,计算出最少添加几个字符使它变成回文字符串(从前向后和从后向前读字符串是一样的)
解题思路:求出字符串和它的倒置字符串的字长公共子序列,用总长度减去最长公共子序列的长度即可得到答案,因为在最长公共子序列的部分不需要再添加字符,而在不是最长公共子序列的位置上插入和另外一个字符串数组相同的字符即可。
AC代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char str1[5010],str2[5010];
short f[5010][5010]; //当定义成int类型时会超内存,定义成short时,内存:49340K,时间:1032MS
int max(int a,int b) //求最大值
{
if(a>=b)
return a;
else
return b;
}
void exchange(int n) //将输入的字符串数组倒置
{
int i,j;
for(i=1;i<=n;i++)
{
scanf("%c",&str1[i]);
}
for(i=n,j=1;i>=1;i--,j++)
{
str2[j]=str1[i];
}
}
int dp(int n) //动态规划求最长公共子序列,核心代码
{
int i,j;
memset(f,0,sizeof(f));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(str1[i]==str2[j])
f[i][j]=f[i-1][j-1]+1;
else if(str1[i]!=str2[j])
f[i][j]=max(f[i-1][j],f[i][j-1]);
}
}
return f[n][n];
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
getchar();
exchange(n);
printf("%d\n",n-dp(n));
}
return 0;
}