1513 Palindrome【lcs】

来源:互联网 发布:淘宝卖家购物车营销 编辑:程序博客网 时间:2024/05/16 12:51

Palindrome

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3907    Accepted Submission(s): 1335


Problem 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.
 

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
5Ab3bd
 

Sample Output
2

题意:

给出一个数字,代表一个字符串的长度,下一行是一个字符串,让你求出至少加几个字符可以把这个字符串变成回文字符串(回文是啥?百度呗...)....


分析,需要求最少加多少字符形成回文串,那么可以这样考虑,因为是想要回文的字符串,那么就拿字符串本身和本身反过来比较,先求出最长公共子序列,为什么呢,想想看,如果公共子字符有很多,那么在加字符的时候不是就可以少考虑很多了吗?也就是说,让这个字符串的长度减去最长公共子序列,求得的就是不能形成回文匹配的数值,也就是所需要的数值!!

 lcs ,比较经典的做法就是开个数组进行动态打表,但是,这个题要求的数据比较大,按一般的要求开二维数组会超内存(2500万啊),然后想啊想

,重新理解了一下这个算法的运转过程,才发现一个比较神奇的地方:在数组操作的时候,数组的前部分数据已经没有了实际意义,也就是浪费了空间!!

因为这个算法吗,从头到尾操作的只有两行的数组(或者两列),然后只需要对下标取余运算,就相当于这个数组可以来回储存有效值,而且不会超内存!

自己也就是大胆想出来的做法,没想到学长竟然说这是所谓的滚动数组的实现,嘿嘿,有时候感觉真的可以多想一点,至少拓展思路没什么错的,多思考才能发现更多别人发现不了的东西!!哈哈~~


ps:自己模拟一下lcs的运转过程,就会发现,第一维数组完全不必要开太大,够用就行...


#include<stdio.h>#include<string.h>#define max(a,b) a>b?a:b;char x[5005];int y[5][5005];//!!!这里完全可以把第一维开到2,不过开多点也没错...int main(){    int i,j,len;    while(~scanf("%d",&len))    {        getchar();        scanf("%s",x);        memset(y,0,sizeof(y));//清零        for(i=1;i<=len;++i)        {            for(j=1;j<=len;++j)            {                if(x[i-1]==x[len-j])                {                    y[i%5][j]=y[(i-1)%5][j-1]+1;//完全和平时的一样                }                else                {                    y[i%5][j]=max(y[i%5][j-1],y[(i-1)%5][j]);                }            }        }        printf("%d\n",len-y[len%5][len]);//这个就是需要的数值    }    return 0;}





0 0