51nod 1006 最长公共子序列Lcs【模板】

来源:互联网 发布:python 目录名称无效 编辑:程序博客网 时间:2024/05/20 08:44

给出两个字符串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

dp的经典题。《程序设计在线》一书上有LCS的讲解,不过书上比这题简单一点的是直接求最长公共子序列长度,而不用回溯输出子序列。

#include<stdio.h>#include<string.h>#define N 1000char str1[N+10],str2[N+10];int a[N+10][N+10],b[N+10][N+10];void LCS(char *x,char *y,int n,int m,int a[][N+10],int b[][N+10] ){//找到最长公共子序列    int i,j;    for(i = 0; i <= n; i ++)        a[i][0] = 0;    for(j = 0; j <= m; j ++)        a[0][j] = 0;    for( i = 1; i <= n; i ++)        for( j = 1; j <= m; j ++)        {            if(x[i-1] == y[j-1])            {//下标从0开始,故为i-1,j-1。                a[i][j] = a[i-1][j-1]+1;                b[i][j] = 1;             }            else             {                if( a[i-1][j] > a[i][j-1])                {                    a[i][j] = a[i-1][j] ;                    b[i][j] = 0;                }                else                {                    a[i][j] = a[i][j-1] ;                    b[i][j] = -1;                }            }        }    return;}void PrintLcs(char *s,int n,int m,int b[][N+10]){//回溯输出子序列    if( 0 == n|| 0 == m)        return;    else if( b[n][m] == 1)    {        PrintLcs(s,n-1,m-1,b);        printf("%c",s[n-1]);    }    else if( b[n][m] == 0)    {        PrintLcs(s,n-1,m,b);    }    else if(b[n][m] == -1)        PrintLcs(s,n,m-1,b);}int main(){    int l1,l2;    int i,j;    while(scanf("%s",str1)!=EOF)    {        scanf("%s",str2);        l1 = strlen(str1);        l2 = strlen(str2);        LCS(str1,str2,l1,l2,a,b);        PrintLcs(str1,l1,l2,b);        printf("\n");    }    return 0;}
原创粉丝点击