1. 程式人生 > >1006 最長公共子序列Lcs

1006 最長公共子序列Lcs

scan gray 16px 最長公共子序列 pre std pri 第一個 put

給出兩個字符串A B,求A與B的最長公共子序列(子序列不要求是連續的)。

比如兩個串為: abcicba abdkscab ab是兩個串的子序列,abc也是,abca也是,其中abca是這兩個字符串最長的子序列。 Input
第1行:字符串A
第2行:字符串B
(A,B的長度 <= 1000)
Output
輸出最長的子序列,如果有多個,隨意輸出1個。
Input示例
abcicba
abdkscab
Output示例
abca

一開始用動態規劃來算出有多長,然後從最後回朔,依次判斷。
 1 #include <stdio.h>
 2 #define  MAXN  1002
 3
char A[MAXN] = {0}; 4 char B[MAXN] = {0}; 5 char R[MAXN] = {0}; 6 short mat[MAXN][MAXN] = {0}; 7 //返回三個數的最大值 8 short max(short a, short b, short c) { 9 if (a > b) { 10 b = a; 11 } 12 return b > c ? b : c; 13 } 14 int main() { 15 int i, j = 0, k; 16 scanf("%s %s", A + 1
, B + 1); 17 for (i = 1; A[i]; i++) { 18 for (j = 1; B[j]; j++) {//利用動態規劃算出最長公共子序列 19 mat[i][j] = max(mat[i - 1][j], mat[i][j - 1], mat[i - 1][j - 1] + (A[i] == B[j] ? 1 : 0)); 20 } 21 } 22 i--; 23 j--; 24 k = MAXN - 1; 25 while (i > 0 && j > 0
) {//從後往前回朔,相等則倒序存入一個字符數組中。 26 if (A[i] == B[j]) { 27 R[k--] = A[i]; 28 i--; 29 j--; 30 } else if (mat[i - 1][j] > mat[i][j - 1]) { 31 i--; 32 } else { 33 j--; 34 } 35 } 36 printf("%s\n", R + k + 1);//算好存入的長度,從第一個地址開始輸出。 37 return 0; 38 }

1006 最長公共子序列Lcs