最近一直在学习算法,基本上都是在学习动态规划以及字符串。当然,两者交集最经典之一则是LCS问题。
首先LCS的问题基本上就是在字符串a,b之间找到最长的公共子序列,比如 YAOLONGBLOG 和 YCLPBPG,其最长公共子序列则是YLBG
当然当字符串比较大时候,枚举则略显困难。
首先我们先考虑求一个基本问题,就是LCS的长度。
很容易可以理解递推式:
当a[i]==b[j],c[i][j]=c[i-1][j-1]+1;
当a[i]!=b[j], c[i][j]=max(c[i-1][j],c[i][j-1]);
对应HDU1159.
abcfbc abfcab programming contest abcd mnp
4 2 0
#include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std; #define MAX 1000 int c[MAX][MAX]; int LCS(string a,string b){ int n=a.length(); int m=b.length(); memset(c,0,sizeof(c)); int i,j; for(i=1;i<=n;i++) for(j=1;j<=m;j++){ if(a[i-1]==b[j-1]){ c[i][j]=c[i-1][j-1]+1; }else { c[i][j]=c[i][j-1]>c[i-1][j]?c[i][j-1]:c[i-1][j]; } } return c[n][m]; } int main(){ string a,b; while(cin>>a>>b){ cout<<LCS(a,b)<<endl; } return 0; }
/*******************************************************************************/ /* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux * Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) * Encoding : UTF8 * Date : 2014-03-197 * All Rights Reserved by yaolong. *****************************************************************************/ /* Description: *************************************************************** *****************************************************************************/ /* Analysis: ****************************************************************** *****************************************************************************/ /*****************************************************************************/ #include <iostream> #include <string> #include <cstring> using namespace std; int max(int a,int b){ return a>b?a:b; } template<typename Iterator> int * lcsLength(Iterator x,Iterator y,int m,int n){ int *c=new int[(m+1)*(n+1)],i,j; for(i=1;i<=m;i++) c[i*(n+1)]=0; for(j=0;j<=n;j++) c[j]=0; for(i=1;i<=m;i++) for(j=1;j<=n;j++) if(*(x+i-1)==*(y+j-1)) c[i*(n+1)+j]=c[(i-1)*(n+1)+j-1]+1; else c[i*(n+1)+j]=max(c[(i-1)*(n+1)+j],c[(i)*(n+1)+j-1]); return c; } template<typename Iterator> void printLCS(int *c,int n,Iterator x,Iterator y,int i,int j){ if(i==0||j==0) return; if( *(x+i-1)==*(y+j-1) ){ printLCS(c,n,x,y,i-1,j-1); cout<<*(x+i-1); }else if(c[(i-1)*(n+1)+j]>=c[i*(n+1)+j-1]) printLCS(c,n,x,y,i-1,j); else printLCS(c,n,x,y,i,j-1); } int main(){ char *x="ACCGGTCGAGTGCGCGGAAGCCGGCCGAA", *y="GTCGTTCGGAATGCCGTTGCTCTGTAAA"; int *c; int n=strlen(x),m=strlen(y); c=lcsLength(x,y,n,m); printLCS(c,m,x,y,n,m); cout<<endl<<c[ n*(m+1)+m]<<endl; delete []c; return 0; }