最长公共子序列 NYOJ37
http://acm.nyist.net/JudgeOnline/problem.php?pid=37
先逆转原来的字符串,再用原来的字符串跟逆转后的字符串进行比较,求得的最长公共子序列就是回文串,也就是不需要添加的,再用总长度减去最长公共子序列就可以得到最少需要添加的字符数。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 int f[1010][1010];//DP数组 5 int b[1010][1010];//记录方向 6 int n,m;//字符串的长 7 void lcs(char x[],char y[],int m,int n) 8 { 9 int i,j; 10 for(i=0;i<=m;i++) 11 f[i][0]=0; 12 for(j=0;j<=n;j++) 13 f[0][j]=0; 14 for(i=1;i<=m;i++) 15 { 16 for(j=1;j<=n;j++) 17 { 18 if(x[i-1]==y[j-1]) 19 { 20 f[i][j]=f[i-1][j-1]+1; 21 b[i][j]=0;//左上 22 } 23 else if(f[i-1][j]>=f[i][j-1]) 24 { 25 f[i][j]=f[i-1][j]; 26 b[i][j]=1;//上 27 } 28 else 29 { 30 f[i][j]=f[i][j-1]; 31 b[i][j]=-1;//左 32 } 33 } 34 } 35 } 36 void printlcs(char x[],int i,int j) 37 { 38 if(i==0||j==0) 39 return; 40 if(b[i][j]==0) 41 { 42 printlcs(x,i-1,j-1); 43 printf("%c",x[i-1]); 44 } 45 else if(b[i][j]==1) 46 { 47 printlcs(x,i-1,j); 48 } 49 else 50 printlcs(x,i,j-1); 51 } 52 int main() 53 { 54 int t,i,j; 55 char x[1001],y[1001]; 56 scanf("%d",&t); 57 while(t--) 58 { 59 scanf("%s",x); 60 for(i=strlen(x)-1,j=0;i>=0;i--) 61 y[j++]=x[i]; 62 y[j]='\0'; 63 int m=strlen(x),n=strlen(y); 64 lcs(x,y,m,n); 65 //printf("最长公共子串是:\n"); 66 //printlcs(x,m,n); 67 //printf("\n长度是:\n"); 68 printf("%d\n",m-f[m][n]); 69 } 70 //system("pause"); 71 return 0; 72 }