POJ

题意:给你两个单词序列,求出他们的最长公共子序列。

多组数据输入,单词序列长度<=100,单词长度<=30

因为所有组成LCS的单词都是通过 a[i] == b[j] 更新的。

打印序列的时候用mark标记一下,然后回溯找就可以了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <cstring>
#include <string>
using namespace std;

#define maxn 150

vector<string> a, b, ans;
int f[maxn][maxn], mark[maxn][maxn];


void printString(int i, int j)
{
    if (i < 0 || j < 0)
        return;

    if (mark[i][j] == 0)
    {
        ans.push_back(a[i]);
        printString(i-1, j-1);
    }
    else if (mark[i][j] == 1)
    {
        printString(i, j-1);
    }
    else
        printString(i-1, j);
}

int main()
{
    string s;
    while(cin >> s)
    {
        a.clear(); b.clear();

        a.push_back(s);
        string t;
        while(cin >> t)
        {
            if (t == "#") break;
            a.push_back(t);
        }

        while(cin >> t)
        {
            if (t == "#") break;
            b.push_back(t);
        }

        int id = 0, n = a.size(), m = b.size();
        memset(f, 0, sizeof(f));
        memset(mark, 0, sizeof(mark));

        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (a[i] == b[j])
                {
                    f[i][j] = f[i-1][j-1]+1;
                    mark[i][j] = 0;
                }
                else if (f[i-1][j] > f[i][j-1])
                {
                    f[i][j] = f[i-1][j];
                    mark[i][j] = -1;
                }
                else
                {
                    f[i][j] = f[i][j-1];
                    mark[i][j] = 1;
                }

        ans.clear();
        printString(n-1, m-1);

        for (int i = ans.size()-1; i > 0; i--)
            cout << ans[i] << " ";

        cout << ans[0] << endl;
    }
}
原文地址:https://www.cnblogs.com/ruthank/p/9353294.html