LCS-最长公共子序列

      从前只是听说过LCS这个弱小的再不能弱小的DP,今天打出来,输出序列那一部分还是费了一些功夫。现在把这段基础得不能再基础的O(n2)代码发出来供大家BS。

 

 

【题目描述】
一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串。如A=“cdaad”,顺次选1,3,5个字符就构成子串“cad”,现给定两个字符串,求它们的最长共公子串。

【输入格式】
第一行两个整数n和m,本别表示两个串的长度。
第二、三行分别是一个字符串。

【输出格式】
 最长子串的长度和这个子序列(每个字母用空格隔开)。

【样例输入】
5 4
abccd
aecd

【样例输出】
3
a c d

 

 

      参考代码:

 

1 program lcs;
2 var
3 a,b:array[1..1000]of char;
4 f:array[0..1000,0..1000]of integer;
5 n,m,j,i:integer;
6 function max(x,y:integer):integer;
7 begin
8 if x>y then exit(x)
9 else exit(y);
10  end;
11 procedure print(i,j:integer); //通过递归输出序列
12 begin
13 if(i=0)or(j=0)then exit;
14 if a[i]=b[j] then
15 begin
16 print(i-1,j-1);
17 if f[i,j]=f[n,m] then writeln(a[i])
18 else write(a[i],' ');
19 end
20 else begin
21 if f[i,j-1]>f[i-1,j]then print(i,j-1)
22 else print(i-1,j);
23 end;
24 end;
25 begin
26 readln(n,m);
27 for i:=1 to n do read(a[i]);
28 readln;
29 for i:=1 to m do read(b[i]);
30 for i:=1 to n do //动态规划找最大的长度
31 for j:=1 to m do //f[i,j]表示a[1~i],b[1~j]区间里公共子串的长度
32 if a[i]=b[j] then f[i,j]:=f[i-1,j-1]+1
33 else f[i,j]:=max(f[i-1,j],f[i,j-1]);
34 writeln(f[n,m]);
35 print(n,m);
36 end.

 

 

(saltless原创,转载请注明出处)

posted on 2010-08-09 10:34  saltless  阅读(493)  评论(2编辑  收藏  举报

导航