POJ 2250 Compromise【LCS】+输出路径(模板题)

题目链接:https://vjudge.net/problem/POJ-2250

题目大意:
给出n组case,每组case由两部分组成,分别包含若干个单词,都以“#”当结束标志,要求输出最长子序列。

#include <iostream>
#include <string>
using namespace std;

string a[105], b[105], ans[105];
int alen, blen, len, dp[105][105], num[105][105];

void LCSLength() {
    memset(dp, 0, sizeof(dp));
    memset(num, 0, sizeof(num));
    for (int i = 1; i <= alen; i++) {
        for (int j = 1; j <= blen; j++) {
            if (a[i] == b[j]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                num[i][j] = 1;
            }
            else if (dp[i - 1][j] >= dp[i][j - 1]) {
                dp[i][j] = dp[i - 1][j];
                num[i][j] = 2;
            }
            else {
                dp[i][j] = dp[i][j - 1];
                num[i][j] = 3;
            }
        }
    }
}

void LCS(int i, int j) {                               //注意打印路径的方法
    if (i == 0 || j == 0) return;
    if (num[i][j] == 1) {
        ans[len--] = a[i];
        LCS(i - 1, j - 1);
    }
    else if (num[i][j] == 2) LCS(i - 1, j);
    else LCS(i, j - 1);
}
    
int main() {                                            //注意输入格式
    string s;
    while (cin >> s) {                                  //由于题目要求输入直到文件结束,所以这里要这样写
        alen = 0, blen = 0;
        a[++alen] = s;
        while (cin >> s) {
            if (s=="#") break;
            a[++alen] = s;
        }
        while (cin >> s) {
            if (s=="#") break;
            b[++blen] = s;
        }
        LCSLength();
        len = dp[alen][blen];
        LCS(alen, blen);
        cout << ans[1];
        for (int i = 2; i <= dp[alen][blen]; i++) cout << " " << ans[i];
        cout << endl;
    }
    return 0;
}

2018-05-18

猜你喜欢

转载自www.cnblogs.com/00isok/p/9056442.html