POJ 2250 Compromise

求文本的最长公共子序列,序列中每个元素都是一个字符串,学习了记录路径和递归输出的方法。

 

/*Accepted 224K 0MS C++ 1186B 2012-04-11 11:19:14 */



#include<cstdio>

#include<cstring>

#include<cstdlib>

#define MAXN 105

#define MAXM 31

int f[MAXN][MAXN];

char a[MAXN][MAXM], b[MAXN][MAXM];

int mark[MAXN][MAXN];

int na, nb, cnt;



void output( int i, int j)

{

    if( i == 0 || j == 0)

        return;

    if( mark[i][j] == 0)

    {

        output( i - 1, j - 1);

        printf( "%s", a[i]);

        cnt ++;

        if( cnt > 0 && cnt != f[na - 1][nb - 1])

            printf( " ");

        else printf( "\n");

    }

    if( mark[i][j] == 1)

        output( i - 1, j);

    if( mark[i][j] == -1)

        output( i, j - 1);

}



void dp()

{

    for( int i = 1; i <= na; i ++)

        for( int j = 1; j <= nb; j ++)

        {

            if( strcmp( a[i], b[j]) == 0)

            {

                mark[i][j] = 0; f[i][j] = f[i - 1][j - 1] + 1;

            }

            else {

                if( f[i - 1][j] > f[i][j - 1]) {

                    mark[i][j] = 1;

                    f[i][j] = f[i - 1][j];

                }

                else {

                    mark[i][j] = -1;

                    f[i][j] = f[i][j - 1];

                }

            }

        }

}



int main()

{

    while( scanf( "%s", a[1]) != EOF)

    {

        if( a[1][0] != '#')

            for( na = 2; scanf( "%s", a[na]) && a[na][0] != '#'; na ++);

        for( nb = 1; scanf( "%s", b[nb]) && b[nb][0] != '#'; nb ++);

        dp();

        cnt = 0;

        output( na - 1, nb - 1);

    }

    return 0;

}

 

 

 

你可能感兴趣的:(Promise)