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

 

你可能感兴趣的:(HDU)