알고리즘 : LIS, DP, 이분탐색, lower bound
풀이1
풀이2
# O(N^2)
def 경로출력(현재위치):
if 이전위치리스트[현재위치] == 현재위치:
print(수열[현재위치], end=' ')
return
경로출력(이전위치리스트[현재위치])
print(수열[현재위치], end=' ')
def 초기화():
전체길이 = int(input(''))
수열 = list(map(int, input('').split(' ')))
길이리스트 = [1]*전체길이
이전위치리스트 = [i for i in range(전체길이)]
return 전체길이, 수열, 길이리스트, 이전위치리스트, float('-inf'), 0
전체길이, 수열, 길이리스트, 이전위치리스트, 최대길이, 최대위치 = 초기화()
for 현재위치 in range(전체길이):
for 이전위치 in range(현재위치):
if 수열[현재위치] > 수열[이전위치]:
if 길이리스트[현재위치] < 길이리스트[이전위치]+1:
길이리스트[현재위치] = 길이리스트[이전위치]+1
이전위치리스트[현재위치] = 이전위치
if 최대길이 < 길이리스트[현재위치]:
최대길이 = 길이리스트[현재위치]
최대위치 = 현재위치
print(최대길이)
경로출력(최대위치)
# O(NlogN)
def 최소위치찾기(시작, 끝, 현재값):
if 시작 > 끝:
return 시작
중간 = (시작+끝)//2
if 증가리스트[중간] >= 현재값:
return 최소위치찾기(시작, 중간-1, 현재값)
else:
return 최소위치찾기(중간+1, 끝, 현재값)
def 초기화():
전체길이 = int(input(''))
수열 = list(map(int, input('').split(' ')))
return 전체길이, 수열, [], [], []
전체길이, 수열, 증가리스트, 최소위치리스트, 경로리스트 = 초기화()
for 현재위치 in range(전체길이):
현재값 = 수열[현재위치]
최소위치 = 최소위치찾기(0, len(증가리스트)-1, 현재값)
최소위치리스트.append(최소위치)
if 최소위치 < len(증가리스트):
증가리스트[최소위치] = 수열[현재위치]
else:
증가리스트.append(수열[현재위치])
현재길이 = len(증가리스트)-1
현재위치 = 전체길이-1
while 현재위치 >= 0:
if 최소위치리스트[현재위치] == 현재길이:
경로리스트.append(str(수열[현재위치]))
현재길이 -= 1
현재위치 -= 1
print(len(증가리스트))
print(' '.join(reversed(경로리스트)))