hdu1503(最长公共子序列加强版)

来源:互联网 发布:成都加工中心编程招聘 编辑:程序博客网 时间:2024/04/28 15:33

题目链接:hdu1503

/*题意:给你两个字符串,要你用这两个字符串组成这样一个字符串,在组成的字符串中字符的相对顺序不变的情况下,可以在组成的字符串中找到原先两个字符串,字母可以错开,但是相对顺序不能变化,要这个组成的字符串中字母数最少,并输出这个字符串。思路:先求出最长公共子序列,同时记录下路径,输出时最长公共子序列的字符只输出一次*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int inf = 0x3f3f3f3f;const int N = 1005;const int mod = 10000;int d[N][N],n,k;int dir[N][N];//表示最长公共子序列从哪个方向继承,1表示从左上方(即d[i-1][j-1]),              //0表示从左边(d[i][j-1]),2表示从上边(d[i-1][j])char a[N],b[N];bool fa[N],fb[N];void LCS(){    int i,j;    int la = strlen(a), lb = strlen(b);    for(i = 1; i <= la; i ++){        for(j = 1; j <= lb; j ++){            if(a[i-1] == b[j-1]) d[i][j] = d[i-1][j-1] + 1, dir[i][j] = 1;            else if(d[i-1][j] > d[i][j-1]){                d[i][j] = d[i-1][j];                dir[i][j] = 2;            }            else{                d[i][j] = d[i][j-1];                dir[i][j] = 0;            }        }    }    memset(fa, false, sizeof(fa));    memset(fb, false, sizeof(fb));    i = la, j = lb;    while(i >= 1 && j >= 1){        if(dir[i][j] == 0)  j --;        else if(dir[i][j] == 1){//标记公共子序列            i --, j --;            fa[i] = fb[j] = true;        }        else if(dir[i][j] == 2) i --;    }    i = j = 0;    while(i < la && j < lb){        while(fa[i] == 0 && i < la){//输出不是公共子序列的字符            printf("%c",a[i]);            i++;        }        while(fb[j] == 0 && j < lb){            printf("%c",b[j]);            j ++;        }        if(i >= la) break;        printf("%c",a[i++]);//公共子序列字符只输出一次        j ++;    }    while(i < la){ printf("%c",a[i]); i ++; }    while(j < lb){ printf("%c",b[j]); j ++; }    printf("\n");}int main(){    //freopen("out.txt","w",stdout);    int x,i,j;    while(~scanf("%s%s",a,b))    {        memset(d, 0, sizeof(d));        memset(dir, -1, sizeof(dir));        LCS();    }    return 0;}


0 0
原创粉丝点击