算法复习之::LCS最长公共子序列

算法思想:dp[i][j]记录到A[i],B[j]的位置是Lcs的最大长度,

    转移方程:I:dp[i][j]=max(dp[i-1][j],dp[i][j]) (i>1)

         II:dp[i][j]=max(dp[i][j-1],dp[i][j]) (j>1)

         III:dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1) (A[i]==A[j],i>1,j>1)

    处理完后,再从dp[A.length][B.length]处开始回溯找出最大子序列。

代码:

  

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;

char A[100],B[100];
int dp[110][110],cnt;
char ans[110];

void ini()
{
    cnt=0;
    scanf("%s",A);
    scanf("%s",B);
    memset(dp,0,sizeof(dp));
    memset(ans,'',sizeof(ans));
}
void DP()
{
    int a=strlen(A),b=strlen(B); 
    for(int i=0;i<a;i++)
        for(int j=0;j<b;j++)
    {
        if(i>0) dp[i][j]=max(dp[i-1][j],dp[i][j]);
        if(j>0) dp[i][j]=max(dp[i][j],dp[i][j-1]);
        if(A[i]==B[j])
        {
            if(i==0 || j==0) dp[i][j]=max(dp[i][j],1);
            else dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
        }
    }
}
void dfs(int i,int j)
{
    if(i==0 || j==0)
    {
        if(A[i]==B[j]) ans[cnt++]=A[i];
        return;
    }
    if(A[i]==B[j] && dp[i][j]>dp[i-1][j-1] && dp[i][j]>dp[i-1][j] && dp[i][j]>dp[i][j-1])
    {
        ans[cnt++]=A[i];
        dfs(i-1,j-1);
    }
    else
    {
        if(dp[i][j]==dp[i-1][j-1]) dfs(i-1,j-1);
        else if(dp[i][j]==dp[i][j-1]) dfs(i,j-1);
        else dfs(i-1,j);
    }
}
int main()
{
    ini();
    DP();
    dfs(strlen(A)-1,strlen(B)-1);
    for(int i=alen-1;i>=0;i--) cout<<ans[i];
    return 0;
}
原文地址:https://www.cnblogs.com/au-xiaotian/p/3372374.html