Baekjoon
#12015. 가장 긴 증가하는 부분 수열2
http://www.acmicpc.net/problem/12015
11053과 같은 문제이지만 N제한이 더 커서 O(N^2)의 방법으로 풀면 시간 초과가 난다. 따라서 O(NlogN) 방법으로 풀어야 한다. 이진 탐색을 활용한 lower bound 알고리즘을 사용했다.
Lower Bound : 배열에서 찾고자 하는 값 k가 있을때 k보다 크거나 같은 값의 첫번째 인덱스를 리턴.
예) 배열 {1, 1, 3, 5, 6} 에서 k=1 일때 Lower Bound = 2(1보다 크거나 같은 값은 3이므로 3의 인덱스인 2를 리턴)
먼저 LIS를 저장할 빈 배열을 하나 생성하여 이를 갱신해나가면서 LIS를 구한다.
입력된 배열 a = {10, 20, 10, 30, 20, 50} 일때 다음과 같은 과정을 거친다.
부분 수열의 최대 길이는 a배열의 크기와 같으므로 같은 크기로 lis 배열을 생성한다.
lis의 마지막 원소의 인덱스인 idx를 통해 부분 수열의 길이를 알 수 있다. 인덱스를 0부터 했으므로 답은 idx+1 이다.
LowerBound를 구하는 알고리즘은 이분탐색과 거의 유사한 구조로 다음과 같이 작동한다.
- start가 end와 같거나 end보다 커지면 그 때 end값이 lower bound이므로 반복문을 종료하고 리턴한다.
- 중간값이 원하는 값보다 작으면 start를 중간값으로 설정하여 다시 탐색한다.
- 중간값이 원하는 값보다 크거나 같으면 end를 중간값으로 설정하여 다시 탐색한다.
이를 코드로 구현하면 다음과 같다.
private static int getLowerBound(int k) {
int start = 0;
int end = idx + 1;
while (start < end) {
int m = (start + end) / 2;
if (lis[m] < k) {
start = m + 1;
} else {
end = m;
}
}
return end;
}
'Algorithms > Baekjoon OJ' 카테고리의 다른 글
[Baekjoon]2468.안전 영역 (0) | 2019.06.24 |
---|---|
[Baekjoon]14502.연구소 (0) | 2019.06.20 |
[Baekjoon]11052.카드 구매하기(DP) (0) | 2019.01.22 |
[Baekjoon]1699.제곱수의 합(DP) (0) | 2019.01.18 |
[Baekjoon]2579.계단오르기(DP) (0) | 2019.01.16 |