11053-s2 성공
This commit is contained in:
54
workbook_7319/silver/11053-s2.py
Normal file
54
workbook_7319/silver/11053-s2.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# 가잔 긴 증가하는 부분 수열
|
||||
|
||||
import sys
|
||||
|
||||
input = sys.stdin.readline
|
||||
|
||||
def binary_search(target, lis):
|
||||
l, r = 0, len(lis)
|
||||
while l < r:
|
||||
mid = (l+r)//2
|
||||
|
||||
if lis[mid] >= target:
|
||||
r = mid
|
||||
else:
|
||||
l = mid + 1
|
||||
|
||||
return l
|
||||
|
||||
def solution():
|
||||
n = int(input().rstrip())
|
||||
|
||||
lst = list(map(int, input().rstrip().split()))
|
||||
|
||||
lis = []
|
||||
|
||||
for k in lst:
|
||||
if not lis or k > lis[-1]:
|
||||
lis.append(k)
|
||||
continue
|
||||
lis[binary_search(k, lis)] = k
|
||||
|
||||
print(len(lis))
|
||||
|
||||
return
|
||||
|
||||
|
||||
solution()
|
||||
|
||||
"""
|
||||
걸린 시간: 10분
|
||||
|
||||
시간 복잡도: 내 풀이는 모든 수를 보는데 그 수가 lis에서 들어갈 자리를 이분탐색으로 확인하기 때문에 O(nlogn)이다.
|
||||
|
||||
해설: 원래는 11055(가장 큰 증가하는 부분수열)번처럼 하나의 수를 볼때 앞에 나온 수중에 본인보다 작은 수의 dp 값을 보고 거기에 +1한 값의 최대가
|
||||
본인을 포함한 증가하는 수열의 길이이다. 근데 이것도 O(n^2)이다.
|
||||
따라서 나는 길이만 알면 되기 때문에 좀 더 시간을 줄여보았다.
|
||||
각 숫자를 순서대로 보면서 lis라는 리스트에 최대한 작은 수들을 넣는 것이다.
|
||||
예를 들어, [1, 5, 8] 이렇게 있을 때, 지금 보는 수가 3이라면 5대신 3으로 바꿔끼면 된다.
|
||||
이렇게 되면 3이 나중에 나온건데, 8이 아직도 있으니까 헷갈릴 수 있다.
|
||||
하지만 이건 lis[i]를 i개의 길이에서 가장 작은 녀석이라고 생각하면 된다.
|
||||
그럼 lis[2]는 2개짜리 수열 중에 제일 큰 놈의 최소가 3으로 됐을 뿐이고, lis[3]은 3개짜리 수열 중에 제일 큰 놈의 최소가 8일 뿐이다.
|
||||
이렇게 진행을 하고 lis[-1]보다 큰 놈이 들어오면 그냥 뒤에 붙이면 된다.
|
||||
이렇게 하면 원래 수열은 모르지만(복원하려면 따로 기록해야 한다.) 최대 길이를 알 수 있다.
|
||||
"""
|
||||
Reference in New Issue
Block a user