51nod 1006 最长公共子序列Lcs(基础dp)

来源:互联网 发布:java线程工作原理 编辑:程序博客网 时间:2024/06/05 17:45

设两个字符串为str1和str2,dp[i][j]表示str1[i]和str2[j]的最长公共子序列,如果str1[i]==str2[j],dp[i][j]=dp[i-1][j-1]+1,如果str1[i]!=str2[j],dp[i][j]=max(dp[i-1][j],dp[i][j-1]),记录公共子序列的时候,和dp的过程差不多
测试案例的dp数组:

输出路径的过程结合dp数组和代码一看就懂了  a b d k s c a ba 1 1 1 1 1 1 1 1 b 1 2 2 2 2 2 2 2 c 1 2 2 2 2 3 3 3 i 1 2 2 2 2 3 3 3 c 1 2 2 2 2 3 3 3 b 1 2 2 2 2 3 3 4 a 1 2 2 2 2 3 4 4 
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 1010;char str1[MAXN];char str2[MAXN];int dp[MAXN][MAXN];char path[MAXN];int plen;void lcs(int len1, int len2){    for(int i = 0; i < len1; ++i)    {        for(int j = 0; j < len2; ++j)        {            if(str1[i] == str2[j])                dp[i+1][j+1] = dp[i][j]+1;            else                dp[i+1][j+1] = max(dp[i+1][j],dp[i][j+1]);        }    }}int main(){    //freopen("out","w",stdout);    scanf(" %s %s",str1,str2);    int len1 = strlen(str1);    int len2 = strlen(str2);    lcs(len1,len2);    int i = len1-1;    int j = len2-1;    plen = 0;    //记录路径    while(i >= 0 && j >= 0)    {        if(str1[i] == str2[j])        {            path[plen++] = str1[i];            --i;            --j;        }        else if(dp[i+1][j] >= dp[i][j+1])//说明lcs是str1[0~i]和str2[0~j-1]的lcs            --j;        else            --i;    }    for(int i = plen-1; i >= 0; --i)        printf("%c",path[i]);    printf("\n");    return 0;}
0 0
原创粉丝点击