반응형
문제
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.
예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이고, 길이는 4이다.
입력
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.
둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (-1,000,000,000 ≤ Ai ≤ 1,000,000,000)
출력
첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.
둘째 줄에는 정답이 될 수 있는 가장 긴 증가하는 부분 수열을 출력한다.
예제 입력 1
6
10 20 10 30 20 50
예제 출력 1
4
10 20 30 50
나의 풀이
O(NlogN)
으로 LIS를 구하기위해서는 lower_bound를 사용하는 알고리즘을 사용해야하는데 이렇게 구하면1 3 4 2
가 입력으로 주어지는 경우 최종으로 구해지는 LIS는1 2 4
가 됩니다. 따라서 이 문제에서는 배열을 앞에서부터 탐색하면서 해당 숫자가 들어갈 수 있는 인덱스에 대한 정보를 배열에 저장하고 이를 역추적하는 방법으로 풀이를 할 수 있습니다.1 3 4 2
를 예로들면 다음과 같습니다.주어진 배열 : [1, 3, 4, 2] 각 원소가 LIS에 위치할 수 있는 인덱스 : [0, 1, 2, 1] 뒤에서부터 (LIS의 길이 - 1)부터 찾아 내려감 : 2(4) -> 1(3) -> 1(1)
코드
# 12738번 가장 긴 증가하는 부분 수열3
def lower_bound(start, end, num):
while start < end:
mid = (start + end) // 2
if tmp[mid] < num:
start = mid + 1
else:
end = mid
return end
n = int(input())
arr = list(map(int, input().split()))
tmp = []
index = [[0, 0] for _ in range(n)]
for i in range(len(arr)):
num = arr[i]
index[i][1] = num
if len(tmp) == 0:
tmp.append(num)
continue
if tmp[-1] < num:
index[i][0] = len(tmp)
tmp.append(num)
else:
idx = lower_bound(0, len(tmp)-1, num)
index[i][0] = idx
tmp[idx] = num
answer = []
idx = len(tmp)-1
for i in range(len(index)-1, -1, -1):
if idx == -1:
break
if idx == index[i][0]:
answer.append(index[i][1])
idx -= 1
print(len(tmp))
print(*answer[::-1])
반응형
'Programming > Algorithm' 카테고리의 다른 글
[백준11779번] 최소비용 구하기 2 / Python3 (0) | 2021.01.06 |
---|---|
[백준9010번] DSLR / Python3 (0) | 2021.01.05 |
[백준12738번] 가장 긴 증가하는 부분 수열 3 / Python3 (0) | 2020.12.28 |
[백준2887번] 행성 터널 / Python3 (0) | 2020.12.26 |
[백준1774번] 우주신과의 교감 / Python3 (0) | 2020.12.25 |