LSC最长公共子序列问题

同网上大多数lcs算法一样。实现都是用dp来实现。状态转移方程就不写了。反正熟练于心。

打印出包含a和b的最短序列。当然,a和b中的字符在新序列中的相对位置是不会改变的。

主要是熟悉一下代码:

#include <cstdio>
#include <cstring>
using namespace std;
char a[1000],b[1000];
int visit[1000][1000],dp[1000][1000];
void pri(int x,int y)
{
    if(x==0&&y==0)
        return ;
    if(visit[x][y]==1)
    {
        pri(x-1,y-1);
        printf("%c",a[x-1]);
    }else if(visit[x][y]==2)
    {
        pri(x-1,y);
        printf("%c",a[x-1]);
    }else if(visit[x][y]==3)
    {
        pri(x,y-1);
        printf("%c",b[y-1]);
    }else if(visit[x][y]==0&&x>0&&y==0)
    {
        pri(x-1,y);
        printf("%c",a[x-1]);
    }else if(visit[x][y]==0&&y>0&&x==0)
    {
        pri(x,y-1);
        printf("%c",b[y-1]);
    }
}
int main()
{
    while (scanf ("%s %s",a,b))
    {
        int la=strlen(a),lb=strlen(b);
        memset(dp,0,sizeof(dp));
        memset(visit,0,sizeof(visit));
        for(int i=1;i<=la;i++)
        {
            for(int j=1;j<=lb;j++)
            {
                if(a[i-1]==b[j-1])
                {
                    dp[i][j]=dp[i-1][j-1]+1;
                    visit[i][j]=1;
                }
                else if(dp[i-1][j]>dp[i][j-1])
                {
                    dp[i][j]=dp[i-1][j];
                    visit[i][j]=2;
                }
                else if(dp[i-1][j]<=dp[i][j-1])
                {
                    dp[i][j]=dp[i][j-1];
                    visit[i][j]=3;
                }
            }
        }
        pri(la,lb);
        printf("
");
    }
    return 0;
}

多熟悉代码。了然于心当然是最好不过了。加油呀。

原文地址:https://www.cnblogs.com/bei-insomia/p/4449141.html