2631-g4 풀이 보고 품

This commit is contained in:
2026-03-16 17:41:09 +09:00
parent 6ad8ca72e6
commit e5f5c64f26

View File

@@ -0,0 +1,55 @@
# 줄세우기
import sys
input = sys.stdin.readline
def binary_search(v, tails):
l, r = 0, len(tails)
while l < r:
mid = (l+r)//2
if tails[mid] >= v:
r = mid
else:
l = mid + 1
return l
def solution():
n = int(input().rstrip())
tails = [int(input().rstrip())]
for _ in range(n-1):
now = int(input().rstrip())
if tails[-1] < now:
tails.append(now)
elif tails[-1] == now:
continue
else:
idx = binary_search(now, tails)
tails[idx] = now
print(n - len(tails))
return
solution()
"""
걸린 시간: 몰라
시간 복잡도:
해설: 최대 길이의 이미 정렬되어 있는 애들을 제외한 애들을 움직이면 된다. -> LIS(가장 긴 증가하는 부분 수열)
두 가지 방법이 있는데,
1) dp[i]는 i번째가 맨 끝인 증가하는 부분 수열의 길이라고 할 때, 이중 for문으로 dp[i]를 볼때 j<i인 arr[j]와 dp[j]를 보면서 dp[i]를 갱신하는 방법이다.
-> O(n^2)
2) tails[i]는 i+1 길이의 증가하는 부분 수열들 중에 맨 끝값 중 최소값이라고 할 때(2 5 8, 2 4 6이 있으면 tails[2]=6),
지금 보는 값이 tails[-1]보다 크다면 tails.append()로 최장 증가 부분 수열의 고점을 높이고,
지금 보는 값이 tails[-1]보다 같다면 그냥 넘어가고,
지금 보는 값이 tails[-1]보다 작다면 tails의 어디에 들어갈지 이분탐색으로 확인해서,
그 인덱스의 값을 교체함으로써 tails[idx]에 최대한 작은 수를 놓고 앞으로의 가능성을 높인다.(tails=[2, 5, 8] 이때 4가 들어오면 tails=[2, 4, 8])
이렇게 하면 최장 증가 부분 수열의 길이를 O(nlogn)에 구할 수 있지만, 실제 수열은 모른다. -> 따로 기록해두어야 함.
"""