Palindrome
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 57426 | Accepted: 19910 |
Description
A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.
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.
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
Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.
Output
Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.
Sample Input
5 Ab3bd
Sample Output
2
Source
有这么个结论,需要加的字符的个数=原来字符串的长度-原来字符串和逆字符串的最长公共子序列的长度;
然后用滚动数组即可。
求最长公共序列的长度:
如左上图,先将该字符串到续,然后在和原来的字符串比较,如果两个字母相同,则将左上角的数字+1,否则该点的值等于该位置的的左边和上边数值的最大值,依次进行,最后右下角的数字极为最长公共子序列。该问题即可解决,但是该题的数据有点大(5000),如果用此方法会超内存!
所以可用滚动数字的方法解决。即:将此数组改成2*5000的即可!
附上别人AC代码:
#include<stdio.h>
#include<string.h>
char str[5010];
char s2[5010];
int dp[2][5010];
int main()
{
int n,i,j;
while(scanf("%d",&n)!=EOF)
{
scanf("%s",str);
for(i=n-1; i>=0; i--)
{
s2[n-i-1]=str[i];
}
s2[n]='\0';
memset(dp,0,sizeof(dp));
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(str[i-1]==s2[j-1])
{
dp[i%2][j]=dp[(i-1)%2][j-1]+1;
}
else
{
//dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
if(dp[(i-1)%2][j]>dp[i%2][j-1])
{
dp[i%2][j]=dp[(i-1)%2][j];
}
else
{
dp[i%2][j]=dp[i%2][j-1];
}
}
}
}
int l=dp[n%2][n];
printf("%d\n",n-l);
}
<span style="white-space:pre"> </span>return 0;
}

本文介绍了一种算法,用于确定将任意给定字符串转换为回文所需的最少字符插入次数。通过计算原字符串与其反转字符串之间的最长公共子序列长度来实现。

被折叠的 条评论
为什么被折叠?



