用一个数组c[i][j]来存从0到第一个字符串位置i与从0到第二个字符串位置j中出现的最长共有子序列的长度。如果字符串一中a[i]等于字符串二中b[j],那么c[i][j]=c[i-1][j-1],注意不是c[i-1][j]或者c[i][j-1],因为比如abc bbf,a[1]==b[1]此时c[1][1]=1,c[0][1]=0,c[1][0]=1;c[0][0]=0,如果c[1][1]=c[1][0]+1,那么就重复计算了bbf中的两个b,事实上只能算一个。当a[i]!=b[j]时,c[i][j]=max(c[i-1][j],c[i][j-1])。
动态方程:
c[i][j]=c[i-1][j-1} (a[i]==a[j])
c[i][j]=max(c[i-1][j],c[i][j-1]) (a[i]!=a[j])
#include <iostream> #include<cstring> #include<stdio.h> using namespace std; char a[1000],b[1000]; int c[1000][1000]; int len_a,len_b; int i,j; int dp(int a,int b) { if(a>=0&&b>=0)return c[a][b]; else return 0; } int main() { while(scanf("%s %s",a,b)!=EOF) { len_a=strlen(a); len_b=strlen(b); for(i=0;i<len_a;i++) { for(j=0;j<len_b;j++) { if(a[i]==b[j]) c[i][j]=dp(i-1,j-1)+1; else c[i][j]=(dp(i-1,j)>dp(i,j-1))?dp(i-1,j):dp(i,j-1); } } printf("%d\n",c[i-1][j-1]); } return 0; }