Skip to content

Commit 6ec21a5

Browse files
committed
b14003 - DP: LIS (n log n, 역추적)
1 parent 34e0b85 commit 6ec21a5

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# 14003번: 가장 긴 증가하는 부분 수열 5 - <img src="https://static.solved.ac/tier_small/16.svg" style="height:20px" /> Platinum V
2+
3+
<!-- performance -->
4+
5+
<!-- 문제 제출 후 깃허브에 푸시를 했을 때 제출한 코드의 성능이 입력될 공간입니다.-->
6+
7+
<!-- end -->
8+
9+
## 문제
10+
11+
[문제 링크](https://boj.kr/14003)
12+
13+
14+
<p>수열 A가 주어졌을 때, 가장 긴 증가하는&nbsp;부분&nbsp;수열을 구하는 프로그램을 작성하시오.</p>
15+
16+
<p>예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&nbsp;수열은&nbsp;A = {<strong>10</strong>,&nbsp;<strong>20</strong>, 10,&nbsp;<strong>30</strong>, 20,&nbsp;<strong>50</strong>} 이고, 길이는 4이다.</p>
17+
18+
19+
20+
## 입력
21+
22+
23+
<p>첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.</p>
24+
25+
<p>둘째 줄에는 수열 A를 이루고 있는 A<sub>i</sub>가 주어진다. (-1,000,000,000&nbsp;≤ A<sub>i</sub>&nbsp;≤ 1,000,000,000)</p>
26+
27+
28+
29+
## 출력
30+
31+
32+
<p>첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.</p>
33+
34+
<p>둘째 줄에는 정답이 될 수 있는 가장 긴 증가하는 부분 수열을 출력한다.</p>
35+
36+
37+
38+
## 소스코드
39+
40+
[소스코드 보기](가장%20긴%20증가하는%20부분%20수열%205.py)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# ************************************************************************** #
2+
# #
3+
# ::: ::: ::: #
4+
# Problem Number: 14003 :+: :+: :+: #
5+
# +:+ +:+ +:+ #
6+
# By: ro1864 <boj.kr/u/ro1864> +#+ +#+ +#+ #
7+
# +#+ +#+ +#+ #
8+
# https://boj.kr/14003 #+# #+# #+# #
9+
# Solved: 2024/07/15 10:49:11 by ro1864 ### ### ##.kr #
10+
# #
11+
# ************************************************************************** #
12+
13+
import sys
14+
input = sys.stdin.readline
15+
16+
def b_search(target, arr):
17+
s = 0
18+
e = len(arr) - 1
19+
while s <= e:
20+
mid = (s + e) // 2
21+
if target == arr[mid]:
22+
return mid
23+
elif target < arr[mid]:
24+
e = mid - 1
25+
else:
26+
s = mid + 1
27+
return s
28+
29+
def lis(a):
30+
dp = [(0, a[0])] # 모든 기록
31+
li = [a[0]]
32+
for i in range(1, len(a)):
33+
if a[i] > li[-1]:
34+
li.append(a[i])
35+
dp.append((len(li) - 1, a[i]))
36+
else:
37+
idx = b_search(a[i], li)
38+
li[idx] = a[i]
39+
dp.append((idx, a[i]))
40+
return dp, li
41+
42+
def backtracking(li, dp):
43+
s = []
44+
order = len(li) - 1
45+
for i in range(len(dp) - 1, -1, -1):
46+
if dp[i][0] == order:
47+
s.append(dp[i][1])
48+
order -= 1
49+
s.reverse()
50+
return s
51+
52+
53+
n = int(input())
54+
a = list(map(int, input().split()))
55+
56+
dp, li = lis(a)
57+
print(len(li))
58+
print(*backtracking(li, dp))

0 commit comments

Comments
 (0)