hdu1503(最长公共子序列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

题意:由两个字符串构造出另一个字符串,该字符串包含前两个字符串(按字符顺序,但不一定连续),使该字符串长度最小

分析:dp[i][j]表示s1[0-i]与s2[0-j]的最长公共子串.用数字flag随便记录路径然后回溯输出答案即可。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 10010
using namespace std;
char s1[110],s2[110];
int dp[110][110],flag[110][110];
void print(int x,int y)
{
    if(x==0&&y==0)return;
    if(flag[x][y]==0)
    {
        print(x-1,y-1);
        printf("%c",s1[x-1]);
    }
    else if(flag[x][y]==1)
    {
        print(x,y-1);
        printf("%c",s2[y-1]);
    }
    else
    {
        print(x-1,y);
        printf("%c",s1[x-1]);
    }
}
int main()
{
    while(scanf("%s%s",s1,s2)>0)
    {
        int len1=strlen(s1);
        int len2=strlen(s2);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=len1;i++)flag[i][0]=-1;;//这个时刻s1[i]要单独输
        for(int i=0;i<=len2;i++)flag[0][i]=1;;//这个时刻s2[i]要单独输
        for(int i=1;i<=len1;i++)
        for(int j=1;j<=len2;j++)
        {
            if(s1[i-1]==s2[j-1])
            {
                dp[i][j]=dp[i-1][j-1]+1;
                flag[i][j]=0;//表示这个时刻属公共部分
            }
            else if(dp[i][j-1]<dp[i-1][j])
            {
                dp[i][j]=dp[i-1][j];
                flag[i][j]=-1;//这个时刻s1[i-1]要单独输
            }
            else
            {
                dp[i][j]=dp[i][j-1];
                flag[i][j]=1;//这个时刻s2[j-1]要单独输
            }
        }
        print(len1,len2);puts("");
    }
}
View Code
原文地址:https://www.cnblogs.com/lienus/p/4149056.html