LCS

来源:互联网 发布:苹果看视频软件 编辑:程序博客网 时间:2024/04/28 13:07
                                                                   Hdu--Palindrome
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
 

有这么个结论,需要加的字符的个数=原来字符串的长度-原来字符串和逆字符串的最长公共子序列的长度。

#include<stdio.h>#include<string.h>int n;char a[5010];int dp[2][5010];int max(int x,int y){return x>y?x:y;}int lcs(){memset(dp,0,sizeof(dp));int len1=n;int len2=n;int i,j;for(i=n;i>=1;i--){for(j=1;j<=len2;j++){if(a[i-1]==a[j-1]){dp[(len1-i+1)%2][j]=dp[(len1-i)%2][j-1]+1;}elsedp[(len1-i+1)%2][j]=max(dp[(len1-i)%2][j],dp[(len1-i+1)%2][j-1]);}}    return dp[len1%2][len2];}int main(){int sum;while(scanf("%d",&n)!=EOF){scanf("%s",a);sum=n-lcs();printf("%d\n",sum);}return 0;}




 

 

滚动数组很适合用在二维DP而且是数组在很大时,可以节省内存,消除超内存的隐患!具体思想还是看了网上的资料,转载一个,共同享用吧!
滚动数组 举个简单的例子:
int i,d[100];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i]=d[i-1]+d[i-2];
printf("%d",d[99]);
上面这个循环d[i]只需要解集中的前2个解d[i-1]和d[i-2];
为了节约空间用滚动数组的方法


int d[3];
d[0]=1;d[1]=1;
for(i=2;i<100;i++)
d[i%3]=d[(i-1)%3]+d[(i-2)%3];
printf("%d",d[99%3]);


注意上面的运算,我们只留了最近的3个解,数组好象在“滚动?一样,所以叫滚动数组


对于二维数组也可以用这种方法 例如:
int i,j,d[100][100];
for(i=1;i<100;i++)
    for(j=0;j<100;j++)
        d[i][j]=d[i-1][j]+d[i][j-1];


上?的d[i][j]忪便赖于d[i-1][j],d[i][j-1];
迿用滚动数组
int i,,j,d[2][100];
for(i=1;i<100;i++)
    for(j=0;j<100;j++)
        d[i%2][j]=d[(i-1)%2][j]+d[i%2][j-1];


滚动数组实际是一种节约空间的办法,时间上没什么优势,多用于DP中,举个例子先: 
一个DP,平常如果需要1000×1000的空间,其实根据DP的特点,能以2×1000的空间解决问题,并且通过滚动,获得和1000×1000一样的效果。

0 0
原创粉丝点击