最长公共递增子序列。o(n*m)做法。只在cf上过了。。。poj,zoj都wa出翔了。。。记录路径要开二维数组否则会wa。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL;
#define INF 1000000007
#define N 505
int n, m;
int a[N], b[N];
int f[N][N];
int pre[N][N];
int ans[N];
int main(){
while(scanf("%d", &n) != EOF){
memset(ans, 0, sizeof(ans));
memset(f, 0, sizeof(f));
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
scanf("%d", &m);
for(int i = 0; i < m; i++){
scanf("%d", &b[i]);
}
int mid = 0, mv = 0;
int nid = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
pre[i][j] = j;
}
}
for(int i = 1; i <= n; i++){
int k = 0;
for(int j = 1; j <= m; j++){
f[i][j] = f[i - 1][j];
pre[i][j] = pre[i - 1][j];
if(a[i - 1] > b[j - 1] && f[i][k] < f[i][j]) k = j;
if(a[i - 1] == b[j - 1] && f[i][k] + 1 > f[i][j]){
f[i][j] = f[i][k] + 1;
pre[i][j] = k;
if(f[i][j] > mv){
mv = f[i][j];
mid = j;
nid = i;
}
}
}
}
int x = mid;
int y = nid;
int ptr = 1;
while(pre[y][x] != x){
ans[ptr ++] = b[x - 1];
x = pre[y][x];
}
printf("%d\n", mv);
for(int i = mv; i > 0; i--){
printf("%d ", ans[i]);
}
printf("\n");
}
return 0;
}