JLIS (중, p. 236)
소요시간: 2시간
점화식#
두 수열을 v[0], v[1]로 나타낸다 할 때,
dp[x][y] = v[0][0]~v[0][x], v[1][0]~v[1][y]까지 봤을 때 JLIS의 길이
base case#
두 수열의 index가 1부터 시작한다고 할 때,
if(x+y ≤ 1) return x+y;

#include <bits/stdc++.h>
using namespace std;
int dp[101][101];
long long v[2][101];
int f(int x, int y) {
if(x + y <= 1) return x + y;
int& ret = dp[x][y];
if(ret) return ret;
ret = 1;
if(v[0][x] > v[1][y]) {
for(int i = 0; i < x; i++) {
if(v[0][i] < v[0][x]) {
ret = max(ret, f(i, y) + 1);
}
}
} else if(v[0][x] < v[1][y]) {
for(int i = 0; i < y; i++) {
if(v[1][i] < v[1][y]) {
ret = max(ret, f(x, i) + 1);
}
}
} else {
long long tmp = v[0][x];
for(int i = 0; i < x; i++) {
if(v[0][i] < tmp) {
ret = max(ret, f(i, y));
}
}
for(int i = 0; i < y; i++) {
if(v[1][i] < tmp) {
ret = max(ret, f(x, i));
}
}
}
return ret;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int tc;
cin >> tc;
while(tc--) {
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> v[0][i];
for(int i = 1; i <= m; i++) cin >> v[1][i];
v[0][0]=v[1][0] = -0x3f3f3f3f3f3f3f3fLL;
memset(dp, 0, sizeof(dp));
int ans = 0;
for(int i = 0; i <= n; i++) {
for(int j = 0; j <= m; j++) {
ans = max(ans, f(i, j));
}
}
printf("%d\n", ans);
}
return 0;
}