查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!
问题述描
我们称序列Z = < z1, z2, ..., zk >是序列X = < x1, x2, ..., xm >的子序列当且仅当存在严厉回升的序列< i1, i2, ..., ik >,使得对j = 1, 2, ... ,k, 有xij = zj。比如Z = < a, b, f, c > 是X = < a, b, c, f, b, c >的子序列。
当初给出两个序列X和Y,你的务任是找到X和Y的大最共公子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列。
输入数据
输入括包多组测试数据。每组数据括包一行,给出两个长度不过超200的符字串,表现两个序列。两个符字串之间由若干个空格开隔。
输出要求
对每组输入数据,输出一行,给出两个序列的大最共公子序列的长度。
解题路思
如果我们用符字数组s1、s2寄存两个符字串,用s1[i]表现s1中的第i个符字,s2[j]表现s2中的第j个符字(符字编号从1开始,不存在“第0个符字”),用s1i表现s1的前i个符字所形成的子串, s2j表现s2的前j个符字形成的子串,MaxLen(i, j)表现s1i 和s2j的最长共公子序列的长度,那么递推关系如下:
if( i ==0 || j == 0 ) {
MaxLen(i, j) = 0 //两个空串的最长共公子序列长度当然是0
}
else if( s1[i] == s2[j] )
MaxLen(i, j) = MaxLen(i-1, j-1 ) + 1;
else {
MaxLen(i, j) = Max( MaxLen(i, j-1), MaxLen(i-1, j));
}
// File Name: zuichanggongongzixulielen.cpp // Author: rudolf // Created Time: 2013年04月24日 星期三 15时00分46秒 #include<vector> #include<list> #include<map> #include<set> #include<deque> #include<stack> #include<bitset> #include<algorithm> #include<functional> #include<numeric> #include<utility> #include<sstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<ctime> #define MaxSize 200 #include <stdio.h> #include <string.h> using namespace std; char p[MaxSize+10]; char q[MaxSize+10]; int MaxComLen[MaxSize+10][MaxSize+10]; //MaxComLen[i][j]表现以第一个串第i个素元,第二个串第j个素元为终点的大最共公子串 int main() { int i,j,max; int plen=0,qlen=0; while(scanf("%s%s",p+1,q+1)>0) { int maxlen=0; plen=strlen(p+1); qlen=strlen(q+1); for (i=0;i<=plen;i++) MaxComLen[i][0]=0; for (j=0;j<=qlen;j++) MaxComLen[0][j]=0; //如果i或者j为0,最长共公字串为0 for(i=1;i<=plen;i++) { for (j=1;j<=qlen;j++) { if (p[i]==q[j]) MaxComLen[i][j]=MaxComLen[i-1][j-1]+1; else { if(MaxComLen[i-1][j]>MaxComLen[i][j-1]) MaxComLen[i][j]=MaxComLen[i-1][j]; else MaxComLen[i][j]=MaxComLen[i][j-1]; } if (MaxComLen[i][j]>maxlen) //输出大最的长度,按照义定应该为最后一个素元 maxlen=MaxComLen[i][j]; } } printf("%d\n",maxlen); } return 0; }
int findresult(int pa,int pb) { if(dp[pa][pb]>=0) return dp[pa][pb]; if(pa==0) { int i;int flag=0; for(i=0;i<=pb;i++) if(wordA[pa]==wordB[i]) { dp[pa][i]=1; flag=1; } return flag; } if(pb==0) { int i;int flag=0; for(i=0;i<=pa;i++) if(wordA[i]==wordB[pb]) { dp[i][pb]=1; flag=1; } return flag; } int tmp=MIN; if(wordA[pa]==wordB[pb]) tmp=findresult(pa-1,pb-1)+1; tmp=maxnum(tmp,findresult(pa-1,pb)); tmp=maxnum(tmp,findresult(pa,pb-1)); dp[pa][pb]=tmp; return tmp; }
文章结束给大家分享下程序员的一些笑话语录: 马云喜欢把自己包装成教主,张朝阳喜欢把自己包装成明星,李彦宏喜欢把自己包装成的很知性,丁磊喜欢把自己包装的有创意,李开复总摆出一副叫兽的样子。看来的。其实我想说,缺啥补啥,人之常情。