14002-g4 성공
This commit is contained in:
64
workbook_7319/gold/14002-g4.py
Normal file
64
workbook_7319/gold/14002-g4.py
Normal file
@@ -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를 계속 역추적 하면 하나의 수열이 완성된다.
|
||||
"""
|
||||
Reference in New Issue
Block a user