POJ 1458 Common Subsequence DP LCS 最长公共子序列
最长公共子序列,照抄《算法设计与分析导论》P138-140
设输入的两个字符串分别为a1,a2,```,am(串a)
b1,b2,````,bn(串b)
设d(i,j)为字符串a1,a2,`````,ai和b1,b2,```,bj的最长公共子序列的长度
如果a[i] == b[j],那么d(i,j) = d(i-1,j-1)+1;
如果a[i] != b[j],那么 d(i,j) = max(d(i-1,j) , d(i,j-1))
边界条件为d(0,0) = d(0,j) = d(i,0) = 0,1 <= i <= m,1 <= j <= n
中间为节省空间,用到滚动数组,我为了减少滚动数组时交换的时间,用了个小技巧,看代码就知道了
贴代码:
View Code
1 #include <cstdio> 2 #include <cstring> 3 #define N 500 4 char a[N],b[N]; 5 int d[2][N]; 6 int max(int x,int y) 7 { 8 return x>y?x:y; 9 } 10 int main() 11 { 12 int i,j; 13 // freopen("in.cpp","r",stdin); 14 while(~scanf("%s%s",a,b)) 15 { 16 int l1 = strlen(a); 17 int l2 = strlen(b); 18 for(i=0; i<=l2; ++i)//以l2长度为列长,别写成l1了 19 d[0][i] = 0; 20 d[1][0] = 0; 21 int x=1; 22 for(i=1; i<=l1; ++i) 23 { 24 for(j=1; j<=l2; ++j) 25 { 26 if(a[i-1] == b[j-1]) 27 d[x][j] = d[1-x][j-1]+1; 28 else 29 d[x][j] = max(d[1-x][j],d[x][j-1]); 30 } 31 x = 1-x; //实现滚动,原来为0,现在为1,原来为1,现在为0 32 } 33 printf("%d\n",d[l1%2][l2]);//输出最后结果 34 } 35 return 0; 36 }