문제 링크: https://algospot.com/judge/problem/read/JLIS
수열 두개가 주어질 때 각 수열에서 LIS를 골라 크기순으로 합친 것을 합친 증가 부분 수열이라 부르기로 합시다. 이 중 가장 긴 수열을 합친 LIS, JLIS(Joined LIS)라고 부릅시다.
문제는 두 수열의 JLIS의 길이를 구하는 것이 목표입니다.
\[ jlis(indexA, indexB) = \text{A[indexA]와 B[indexB]에서 시작하는 합친 증가 부분 수열의 최대 길이} \]
점화식을 위처럼 설정해줍니다.
이 증가 부분 수열의 다음 숫자는 A[indexA+1] 이후, 또는 B[indexB+1] 이후의 수열 중 max(A[indexA], B[indexB])보다 큰 수 중 하나가 됩니다.
const ll NEGINF = numeric_limits<ll>::min();
int n, m, A[100], B[100];
int cache[101][101];
int jlis(int indexA, int indexB) {
auto& ret = cache[indexA + 1][indexB + 1];
if (ret != -1) return ret;
ret = 2;
ll a = (indexA == -1 ? NEGINF : A[indexA]);
ll b = (indexB == -1 ? NEGINF : B[indexB]);
ll maxElement = max(a, b);
// 다음 원소 찾기
for (int nextA = indexA + 1; nextA < n; ++nextA)
if (maxElement < A[nextA])
ret = max(ret, jlis(nextA, indexB) + 1);
for (int nextB = indexB + 1; nextB < m; ++nextB)
if (maxElement < B[nextB])
ret = max(ret, jlis(indexA, nextB) + 1);
return ret;
}
A[-1], B[-1]을 계산 편의를 위해 임의로 넣었기 때문에 마지막에 계산 결과에서 A[-1], B[-1]의 개수인 2를 빼야 결과값이 됩니다.
사용할 때는 jlis(-1, -1)-2 처럼 쓰면 됩니다.
반응형
'Online Judge > 알고스팟' 카테고리의 다른 글
[알고스팟][C++] LIS: Longest Increasing Subsequence (0) | 2020.08.21 |
---|---|
[알고스팟][C++] JUMPGAME: 외발 뛰기 (0) | 2020.08.20 |
[알고스팟][C++] FESTIVAL: 록 페스티벌 (0) | 2020.07.24 |
[알고스팟][C++] FIRETRUCKS: 소방차 (0) | 2020.06.22 |
[알고스팟][C++] ROUTING: 신호 라우팅 (0) | 2020.06.20 |