가장 긴 증가하는 부분 수열 5
임의의 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 만든다.
DP
배열이 사용된다.DP
배열의 idx
는 length
를 의미한다.A[i]
의 원소가 LIS
에 포함될 때, 길이가 얼마인지를 저장하는 loc
배열을 사용한다.A
수열에서 idx = 4
를 계산할 때loc[4]
의 값은 이분탐색을 통해 얻은 idx
값을 저장하며 2
가 저장될 것이다.loc
을 역순으로 순회하며, 큰 값부터 차례로 ans
에 누적시킨다. import bisect
N = int(input())
A = list(map(int, input().split()))
DP = [] # idx : 길이, val : 해당 길이에 해당하는 가장 작은 값.
loc = [-1 for _ in range(N)] # 해당 A[idx]의 값이 LIS의 몇 번째 순서에 위치하나?
for i, a in enumerate(A):
idx = bisect.bisect_left(DP, a)
loc[i] = idx
if idx == len(DP):
DP.append(a)
else:
DP[idx] = a
length = len(DP) # LIS의 길이는 DP의 길이와 같다.
ans = [0] * length
lis_idx = length
for i in range(len(loc) - 1, -1, -1): # 역순으로 순회한다.
if loc[i] == lis_idx - 1: # 현재 loc[i]의 값이 현재 채워야할 lis_idx라면
lis_idx -= 1
ans[lis_idx] = A[i] # 값을 채운다.
print(len(ans))
for a in ans:
print(a,end=' ')