LCS(最长公共子序列)dp模板,长度和打印子序列

来源:互联网 发布:mac的option键 编辑:程序博客网 时间:2024/05/21 04:41

参考博客和题目描述http://hzzy-010.blog.163.com/blog/static/79692381200872024242126/

【我的记忆化搜索和递推模版】

[INPUT]

GCCCTAGCG
GCGCAATG

[OUTPUT]

5

GCCTG

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXN 100char a[MAXN], b[MAXN];int lena, lenb, dp[MAXN][MAXN];//dp[i][j]记录字符串a[0~i-1]和字符串b[0~j-1]的最长子序列长度struct NODE{    int x, y;}f[MAXN][MAXN];//f[i][j]记录dp[i][j]的父亲节点,也就是他是由max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+sum(当a[i-1] == b[j-1]时sum = 1,否则为0))继承下来的//【记忆化】寻找两个字符串的最大子序列长度,并记录路径int dfs(int i, int j){    if (-1 != dp[i][j])        return dp[i][j];    if (0 == i || 0 == j)        return dp[i][j] = 0;    if (a[i-1] == b[j-1])    {        dp[i][j] = dfs(i-1,j-1)+1;        f[i][j].x = i-1;        f[i][j].y = j-1;    }    else    {        int buf1 = dfs(i-1,j), buf2 = dfs(i,j-1);        if (buf1 < buf2)            dp[i][j] = buf2,f[i][j].x = i, f[i][j].y = j-1;        else            dp[i][j] = buf1, f[i][j].x = i-1, f[i][j].y = j;    }    return dp[i][j];}//【递推】int sloved(int la, int lb){    memset(dp,0,sizeof(dp));    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, f[i][j].x = i-1, f[i][j].y = j-1;            else if(dp[i-1][j] < dp[i][j-1])            {                dp[i][j] = dp[i][j-1];                f[i][j].x = i;                f[i][j].y = j-1;            }            else            {                dp[i][j] = dp[i-1][j];                f[i][j].x = i-1;                f[i][j].y = j;            }        }    }    return dp[la][lb];}//输出其中一个最长子序列void printans(int i, int j){    if (!i || !j)        return;    int x = f[i][j].x, y = f[i][j].y;    printans(x, y);    if (dp[x][y]+1 == dp[i][j])        printf ("%c", a[i-1]);}int main (){    #ifdef SHY        freopen("e:\\1.txt", "r", stdin);    #endif    while(gets(a))    {        gets(b);        lena = strlen(a);        lenb = strlen(b);        memset(dp,-1,sizeof(dp));        printf ("%d\n", sloved(lena, lenb));        printans(lena, lenb);        printf ("\n");    }    return 0;}


 


 


 

0 0