裸的最长公共子序列,不过这里需要保存路径。
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
map<string,int>stod;
map<int,string>dtos;
char w[40];
int dp[110][110], n1[110], n2[110], pre[110][110];
vector<int>ans;
int main() {
int i, j, id, l1, l2;
while (~scanf("%s", w)) {
id = 0, stod.clear(), dtos.clear();
stod[w] = id, dtos[id] = w;
l1 = l2 = 1;
n1[l1++] = id++;
while (scanf("%s", w)) {
if (strcmp(w, "#") == 0) break;
if (stod.find(w) == stod.end()) stod[w] = id, dtos[id++] = w;
n1[l1++] = stod[w];
}
while (scanf("%s", w)) {
if (strcmp(w, "#") == 0) break;
if (stod.find(w) == stod.end()) stod[w] = id, dtos[id++] = w;
n2[l2++] = stod[w];
}
memset(dp, 0, sizeof(dp));
memset(pre, -1, sizeof(pre));
int t1, t2;
for (i = 1;i < l1;i++) {
for (j = 1;j < l2;j++) {
if (n1[i] == n2[j]) {
t1 = dp[i-1][j-1]+1;
if (t1 > dp[i][j]) dp[i][j] = t1, pre[i][j] = (i-1)*1000+j-1;
}else {
t1 = dp[i-1][j], t2 = dp[i][j-1];
if (t1 > dp[i][j]) dp[i][j] = t1, pre[i][j] = (i-1)*1000+j;
if (t2 > dp[i][j]) dp[i][j] = t2, pre[i][j] = i*1000+j-1;
}
}
}
ans.clear();
t1 = l1-1, t2 = l2-1;
while (pre[t1][t2] != -1) {
if (n1[t1] == n2[t2]) ans.push_back(n1[t1]);
int tm = pre[t1][t2];
t1 = tm/1000, t2 = tm%1000;
}
if (ans.size() == 0) {puts("");continue;}
for (i = ans.size()-1;i > 0;i--) cout << dtos[ans[i]] << " ";
cout << dtos[ans[i]] << endl;
}
}