diff --git a/workbook_7319/gold/14002-g4.py b/workbook_7319/gold/14002-g4.py new file mode 100644 index 0000000..59b929d --- /dev/null +++ b/workbook_7319/gold/14002-g4.py @@ -0,0 +1,64 @@ +# 가장 긴 증가하는 부분 수열 4 + +import sys + +input = sys.stdin.readline + +def binary_search(result, target): + l, r = 0, len(result)-1 + idx = len(result) + while l <= r: + mid = (l+r)//2 + + if result[mid][0] >= target: + idx = mid + r = mid - 1 + else: + l = mid + 1 + + return idx + +def solution(): + n = int(input().rstrip()) + + lst = list(map(int, input().rstrip().split())) + parent = [-1] * (n) + + result = [(lst[0], 0)] + for i in range(1, n): + if lst[i] > result[-1][0]: + parent[i] = result[-1][1] + result.append((lst[i], i)) + continue + idx = binary_search(result, lst[i]) + if result[idx][0] != lst[i]: + result[idx] = (lst[i], i) + if idx != 0: + parent[i] = result[idx-1][1] + + answer = [result[-1][0]] + parent_idx = parent[result[-1][1]] + while parent_idx != -1: + answer.append(lst[parent_idx]) + parent_idx = parent[parent_idx] + + print(len(answer)) + print(*answer[::-1]) + return + + +solution() + +""" +걸린 시간: 39분 + +시간 복잡도: 하나의 수에 대해. 이진탐색을 진행하기 때문에 O(nlogn)이다. + +해설: 가장 긴 증가하는 부분 수열 문제에서 수열 자체를 알아야 하는 문제이다. +기존에 하던 방식은 개수만 원했기 때문에 결과 리스트에 업데이트 하면서 진행했다. +하지만 결과 리스트에 있는 것들은 그것 자체가 수열이 아니고, result[i]는 i개의 증가하는 수열들의 맨 뒤 값 중 가장 작은 값이다. +따라서 result를 업데이트 하면서 현재 보는 수의 바로 이전 수를 기록해놔야 한다.(parent 기록) +바로 이전 수는 result에서 binary_search를 했을 때, 본인이 들어갈 idx의 앞에 있는 수가 내가 맨 뒤일때 최선의 수이다. +따라서 그 수의 idx를 계속 기록하면 된다. +마지막에 result[-1]의 parent를 계속 역추적 하면 하나의 수열이 완성된다. +""" \ No newline at end of file