문제 내용
문제
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이고, 길이는 4이다.
입력
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)
출력
첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.
예제 입력 | 예제 출력 |
6 10 20 10 30 20 50 |
4 |
문제 풀이
2022.02.23 - [Algorithm/with Kotlin] - [백준][코틀린] 11053 가장 긴 증가하는 부분 수열
위 문제의 시리즈 문제이다. 위 문제는 DP로 풀었는데, DP의 시간 복잡도는. O(\(n^2\))이다. 이 시간 복잡도를 줄이는 방법이 바로 이분탐색을 이용하는 풀이이다.
하지만.. 내머리로는 도저히 이분탐색을 어떻게 적용하는지 모르겠었고,, 다른 분의 글을 보고 이해를 했다.
https://jason9319.tistory.com/113?category=670441 ⬅️ 참고 글
해당 아이디어를 이용하여 코틀린으로 풀어보았다!.
</>̆̈ 코드
import java.util.*
fun main() {
val br = System.`in`.bufferedReader()
val n = br.readLine().toInt()
val a = StringTokenizer(br.readLine()).run { IntArray(n) {nextToken().toInt()} }
val arr = mutableListOf(Int.MIN_VALUE)
for (item in a) {
if (arr.last() < item) arr.add(item)
else arr[bisect(arr, item)] = item
}
print(arr.size-1)
}
private fun bisect(arr: MutableList<Int>, n: Int): Int {
var low = 0; var high = arr.lastIndex
while (low <= high) {
val mid = (low + high) / 2
when {
arr[mid] == n -> return mid
arr[mid] > n -> high = mid - 1
else -> low = mid + 1
}
}
return low
}
링크