Skip to content

Commit 1304fa8

Browse files
committed
[Gold IV] Title: 가장 긴 증가하는 부분 수열 4, Time: 8 ms, Memory: 69108 KB -BaekjoonHub
1 parent 07bfb7d commit 1304fa8

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# [Gold IV] 가장 긴 증가하는 부분 수열 4 - 14002
2+
3+
[문제 링크](https://www.acmicpc.net/problem/14002)
4+
5+
### 성능 요약
6+
7+
메모리: 69108 KB, 시간: 8 ms
8+
9+
### 분류
10+
11+
다이나믹 프로그래밍, 역추적
12+
13+
### 제출 일자
14+
15+
2025년 7월 18일 17:01:08
16+
17+
### 문제 설명
18+
19+
<p>수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.</p>
20+
21+
<p>예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {<strong>10</strong>, <strong>20</strong>, 10, <strong>30</strong>, 20, <strong>50</strong>} 이고, 길이는 4이다.</p>
22+
23+
### 입력
24+
25+
<p>첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000)이 주어진다.</p>
26+
27+
<p>둘째 줄에는 수열 A를 이루고 있는 A<sub>i</sub>가 주어진다. (1 ≤ A<sub>i</sub> ≤ 1,000)</p>
28+
29+
### 출력
30+
31+
<p>첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.</p>
32+
33+
<p>둘째 줄에는 가장 긴 증가하는 부분 수열을 출력한다. 그러한 수열이 여러가지인 경우 아무거나 출력한다.</p>
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
let n = Int(readLine()!)!
2+
let s = readLine()!.split { $0 == " " }.map { Int(String($0))! }
3+
4+
// dp[i]: s[i]를 마지막 원소로 하는 가장 긴 증가 부분 수열의 길이
5+
var dp = [Int](repeating: 1, count: n)
6+
// parent[i]: s[i] 앞에 오는 원소의 인덱스 (LIS 구성용)
7+
var parent = [Int](0..<n) // 초기화는 자기 자신을 가리키도록
8+
9+
var maxLength = 0
10+
var lastIndex = 0
11+
12+
if n > 0 {
13+
maxLength = 1
14+
}
15+
16+
for i in 1..<n {
17+
for j in 0..<i {
18+
if s[i] > s[j] {
19+
if dp[i] < dp[j] + 1 {
20+
dp[i] = dp[j] + 1
21+
parent[i] = j // s[i] 앞에 s[j]가 옴
22+
}
23+
}
24+
}
25+
// 현재까지의 최대 길이와 해당 길이의 마지막 인덱스 갱신
26+
if dp[i] > maxLength {
27+
maxLength = dp[i]
28+
lastIndex = i
29+
}
30+
}
31+
32+
// LIS 구성
33+
var answer = [Int]()
34+
if maxLength > 0 { // LIS가 존재할 경우에만
35+
var currentIndex = lastIndex
36+
while dp[currentIndex] != 1 { // 길이가 1이 될 때까지 역추적
37+
answer.append(s[currentIndex])
38+
currentIndex = parent[currentIndex]
39+
}
40+
answer.append(s[currentIndex]) // 마지막으로 길이가 1인 원소 추가
41+
}
42+
43+
44+
print(maxLength)
45+
print(answer.reversed().map { "\($0)" }.joined(separator: " "))

0 commit comments

Comments
 (0)