Greatest Common Increasing Subsequence
原题:Greatest Common Increasing Subsequence
题意:给出两个序列a、b,求最长公共递增子序列。
解法:dp,因为数据范围比较小,我用的是二维,f[i][j]表示a,b到i,j的最长公共递增子序列,然后转移叫好了
#include <iostream>
using namespace std;
#include <stdio.h>
long long a[1000], b[1000], pre[1000][1000][2], maxa[1000];
int n, m, ans, x, y;
int f[1000][1000] = {0};
long long d[1000] = {0};
int max(int x, int y) {
if (x > y) return x;
return y;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
cin >> m;
for (int i = 1; i <= m; i++) {
cin >> b[i];
}
ans = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (a[i] == b[j]) {
f[i][j] = 1;
for (int k = 1; k < i; k++) if (maxa[k]+1 > f[i][j] && a[k] < a[i]) {
for (int l = 1; l < j; l++) if (a[k] == b[l] && f[k][l]+1 > f[i][j]) {
f[i][j] = f[k][l]+1;
}
}
if (f[i][j] > ans) {
ans = f[i][j];
x = i;
y = j;
}
if (f[i][j] > maxa[i]) maxa[i] = f[i][j];
}
}
if (ans == 0) cout << 0 << endl;
else {
cout << ans << endl;
while (1) {
d[++d[0]] = a[x];
ans--;
if (ans == 0) break;
while (1) {
x--;
bool flag = false;
int j;
for (j = y-1; j >= 1; j--)
if (a[x] == b[j] && f[x][j] == ans && a[x] < d[d[0]]) {
flag = true;
break;
}
if (flag) {
y = j; break;
}
}
}
for (int i = d[0]; i > 1; i--) cout << d[i] << " ";
cout << d[1] << endl;
}
}