Description
Input
Output
Sample Input
abcfbc abfcab programming contest abcd mnp
Sample Output
4 2 0
之前实在不会。。问了同学,看了别人的博客。。知道这是动态规划的题。。
实际现在不知道为什么是这样的思想。。但是的确能够解决问题……
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; char a[1000]; char b[1000]; int m[1000][1000]; int main() { int lena,lenb,i,j; while(scanf("%s%s",&a,&b)!=EOF) { memset(m,0,sizeof(m)); lena=strlen(a); lenb=strlen(b); for(i=1;i<=lena;i++) { for(j=1;j<=lenb;j++) { if(a[i-1]==b[j-1]) m[i][j]=m[i-1][j-1]+1; else { if(m[i-1][j]>m[i][j-1]) m[i][j]=m[i-1][j]; else m[i][j]=m[i][j-1]; } } } cout<<m[lena][lenb]<<endl; } return 0; }
以下是一个大神的代码。。。找不到链接了,,sorry
#include<stdio.h> #include<string.h> char a[500],b[500]; char num[501][501]; ///记录中间结果的数组 char flag[501][501]; ///标记数组,用于标识下标的走向,构造出公共子序列 void LCS(); ///动态规划求解 void getLCS(); ///采用倒推方式求最长公共子序列 int main() { int i; strcpy(a,"ABCBDAB"); strcpy(b,"BDCABA"); memset(num,0,sizeof(num)); memset(flag,0,sizeof(flag)); LCS(); printf("%d\n",num[strlen(a)][strlen(b)]); getLCS(); return 0; } void LCS() { int i,j; for(i=1;i<=strlen(a);i++) { for(j=1;j<=strlen(b);j++) { if(a[i-1]==b[j-1]) ///注意这里的下标是i-1与j-1 { num[i][j]=num[i-1][j-1]+1; flag[i][j]=1; ///斜向下标记 } else if(num[i][j-1]>num[i-1][j]) { num[i][j]=num[i][j-1]; flag[i][j]=2; ///向右标记 } else { num[i][j]=num[i-1][j]; flag[i][j]=3; ///向下标记 } } } } void getLCS() { char res[500]; int i=strlen(a); int j=strlen(b); int k=0; ///用于保存结果的数组标志位 while(i>0 && j>0) { if(flag[i][j]==1) ///如果是斜向下标记 { res[k]=a[i-1]; k++; i--; j--; } else if(flag[i][j]==2) ///如果是斜向右标记 j--; else if(flag[i][j]==3) ///如果是斜向下标记 i--; } for(i=k-1;i>=0;i--) printf("%c",res[i]); }
原文:http://blog.csdn.net/zuguodexiaoguoabc/article/details/41985231