Computer Science
수열 편집, 재배치, 중첩 문제에서 어떻게 LIS를 활용하는가?
Balang
2025. 4. 22. 19:13
728x90
LIS(Longest Increasing Subsequence)는 알고르짐 입문자에게는 필수지만,
실전 코딩테스트나 알고르짐 경시에서는 단순 LIS 문제가 거의 출제되지 않습니다.
대신, LIS를 응용하거나 변형해서 풀어야 하는 문제가 다양하게 등장합니다.
예를 들어:
- 수열을 최소 횟수로 정렬하는 법
- 정렬을 방해하는 "장애물 수열" 탐지
- 여러 수열을 동시에 중첩 배치하는 문제
- 문자열, 트리 구조, LCS 문제를 LIS로 환원하는 문제 등
실전에서 자주 등장하는 변형 유형 5가지
유형 | 키워드 | 핵심 로직 |
정렬 최소 편집 | 정렬을 위해 제거해야 할 최소 원소 수 | n - LIS |
수열 재배치 최적화 | 재배치 횟수 최소화 | LIS 활용 |
두 수열 매핑 | LCS 문제를 LIS로 변환 | 위치 배열 매핑 |
장애물/포함 관계 처리 | 중첩 가능한 상자/사람/건물 수 최대 | 정렬 + LIS |
LIS 복수 추적 | 경로 개수 구하기 | DP + count 테이블 |
변형 유형 1 – 정렬을 위한 최소 편집
정렬되지 않은 수열을 정렬하려면 어떤 원소들을 "빼야" 하는가?
arr = [3, 7, 5, 2, 6, 1, 4]
→ LIS = [3, 5, 6] → 길이 3
→ 정렬 위해 제거해야 할 최소 수 = len(arr) - LIS = 7 - 3 = 4
활용 문제
- 백준 18353 병사 배치하기 (감소하는 수열 정렬 → LDS 사용)
변형 유형 2 – 수열 재배치 최적화
예: 한 줄로 세운 사람의 키가 입력됨
최대로 줄 세울 수 있는 사람 수는?
그 외의 사람은 재배치하거나 제거해야 함
핵심은:
- 증가 수열을 만들기 위해 필요한 최소 작업 수
- 전체 수 - LIS 길이
변형 유형 3 – 두 수열 매핑 문제 (LCS → LIS 환원)
두 수열의 공통 부분을 유지하면서 최대 정렬 형태를 만들고 싶을 때
예: LCS 문제를 LIS 문제로 바꾸는 전략
예제 문제: 백준 13711
- 두 수열 A, B가 주어짐
- A의 원소 순서를 유지하며, B와의 공통 부분 수열을 최장으로 만들고 싶다
해결 전략:
- B의 원소를 인덱스로 매핑
- A에서 B에 포함된 원소들의 인덱스 시퀀스를 만든 후
- 그 인덱스 배열에 대해 LIS를 구함
# 예:
A = [3, 1, 2, 4]
B = [1, 2, 3, 4]
→ B 인덱스 매핑: {1:0, 2:1, 3:2, 4:3}
→ A 매핑: [2, 0, 1, 3]
→ LIS([2, 0, 1, 3]) = 3
변형 유형 4 – 중첩 구조: 상자/사람/건물 포함 최대
예시:
- 상자들이 (가로, 세로) 형태로 주어짐
- 한 상자가 다른 상자에 들어가려면 두 차원 모두 작아야 함
핵심 아이디어:
- 한쪽 차원 기준 정렬
- 나머지 차원에 대해 LIS 적용
boxes = [(5,4), (6,4), (6,7), (2,3)]
→ 너비 오름차순, 높이 내림차순 정렬 → [(2,3), (5,4), (6,7), (6,4)]
→ LIS on 높이: [3, 4, 7]
활용 문제
- 백준 1965: 상자 넣기
변형 유형 5 – LIS 경로의 개수 구하기
LIS의 길이만이 아니라, 그 가능한 경로 수까지 구해야 하는 경우
접근 방식:
- dp[ i ] : i를 마지막으로 하는 LIS의 길이
- Count[ i ] : 해당 길이로 끝나는 LIS 경로 수
→ 전체 max(dp[ i ]) 길이에 대해, count[ i ] 를 더하면 됨
실전 문제에 어떻게 접근할 것인가?
문제 형태 | 접근 방식 |
수열 길이만 필요한 경우 | 기본 LIS (DP or 이분 탐색) |
경로 복원 | prev[] 추적 or 역추적 구현 |
제거 횟수 최소화 | n - LIS 공식 적용 |
두 수열 비교 | 인덱스 매핑 + LIS |
2D 구조 포함 문제 | 정렬 + LIS |
요약
- 실전에서는 LIS 자체보다 응용/변형이 훨씬 자주 등장
- 정렬/재배치 문제 → n - LIS
- 이중 수열/중첩 구조 → 정렬 + LIS 조합
- 두 수열 비교 문제 → 인덱스 매핑 후 LIS
- 수열 복원 or 경로 수 계산 → prev[] or count[] 활용
728x90
반응형