51 nod 最长公共子序列问题(打印路径)

输入

第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)

输出

输出最长的子序列,如果有多个,随意输出1个。

输入示例

abcicba
abdkscab


输出示例

abca

请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。

不同语言如何处理输入输出,请查看下面的语言说明。

题目链接:

https://www.51nod.com/tutorial/course.html#!courseId=4

题意:

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。

比如两个串为:

abcicba

abdkscab

ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。

解题思路:

我们有两个字符串a[i]和b[i],设一个二维数组dp[i][j]表示a的i位和b的j位之前的最长公共子序列的长度。

1.a[i]=b[j]时,那么最长公共子序列的最后一个元素一定是这个元素。就有:dp[i][j]=dp[i-1][j-1]+1;

2.a[i]≠b[i]时,如果最长公共子序列中最后一个元素不等于a[i],那么最长公共子序列跟a[i]就没有关系,就有dp[i][j]=dp[i-1][j]

如果最长公共子序列中最后一个元素不等于b[i],那么最长公共子序列跟b[i]就没有关系,就有dp[i][j]=dp[i][j-1]

可是你事先并不知道最长公共子序列中最后一个元素和a[i],b[i]与没有关系,所以就有dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

回溯法标记路径:

由上面我们可以知道dp[i][j]的来源有三个

那么我们在计算dp[i][j]时,可以用x[i][j]来做标记,用来记录dp[i][j]是从哪个方向来的。用递归回溯的方法就可以打印路径。

AC代码:

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
int dp[1001][1001],x[1001][1001];
char a[1001],b[1001];
void print_load(int i,int j)
{
    if(i==0||j==0)
        return;
    if(x[i][j]==0)
    {
        print_load(i-1,j-1);
        printf("%c",a[i-1]);
    }
    else if(x[i][j]==1)
        print_load(i,j-1);
    else
        print_load(i-1,j);
}
int main()
{
    while(~scanf("%s%s",a,b))
    {
        memset(dp,0,sizeof(dp));
        int a1=strlen(a);
        int b1=strlen(b);
        for(int i=1;i<=a1;i++)
        {
            for(int j=1;j<=b1;j++)
            {
                if(a[i-1]==b[j-1])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    x[i][j]=0;
                }
                else if(dp[i][j-1]>dp[i-1][j])
                {
                    dp[i][j]=dp[i][j-1];
                    x[i][j]=1;
                }
                else
                {
                    dp[i][j]=dp[i-1][j];
                    x[i][j]=-1;
                }
            }
        }
        print_load(a1,b1);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/81257394
今日推荐