HDU-1053:Advanced Fruits(LCS+路径保存)

链接:HDU-1053:Advanced Fruits

题意:将两个字符串合成一个串,不改变原串的相对顺序,可将相同字母合成一个,求合成后最短的字符串。

题解:LCS有三种状态转移方式,将每个点的状态转移方式记录下来,再回溯。

#include <bits/stdc++.h>
using namespace std;

const double EPS = 1e-6;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int maxn = 100 + 10;
char s[maxn], t[maxn];
int slen, tlen;
int dp[maxn][maxn], p[maxn][maxn];

void LCS()
{
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i <= slen; i++) p[i][0] = 1;
    for(int i = 0; i <= tlen; i++) p[0][i] = -1;

    for(int i = 1; i <= slen; i++){
        for(int j = 1; j <= tlen; j++){
            if(s[i] == t[j]){
                dp[i][j] = dp[i-1][j-1] + 1;
                p[i][j] = 0;
            }
            else if(dp[i-1][j] >= dp[i][j-1]){
                dp[i][j] = dp[i-1][j];
                p[i][j] = 1;
            }
            else{
                dp[i][j] = dp[i][j-1];
                p[i][j] = -1;
            }
        }
    }
}

void PrintLcs(int i, int j)
{
    if(!i && !j) return ;
    if(p[i][j] == 0){
        PrintLcs(i-1, j-1);
        putchar(s[i]);
    }
    else if(p[i][j] == 1){
        PrintLcs(i-1, j);
        putchar(s[i]);
    }
    else if(p[i][j] == -1){
        PrintLcs(i, j-1);
        putchar(t[j]);
    }
}

int main()
{
    while(scanf("%s%s", s + 1, t + 1) != EOF){
        slen = strlen(s + 1);
        tlen = strlen(t + 1);

        LCS();
        PrintLcs(slen, tlen);

        puts("");
    }

    return 0;
}

 

posted @ 2018-07-26 09:55  鬼沐冢  阅读(174)  评论(0编辑  收藏  举报