11let n = Int ( readLine ( ) !) !
22let s = readLine ( ) !. split { $0 == " " } . map { Int ( String ( $0) ) ! }
33
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) // 초기화는 자기 자신을 가리키도록
4+ var parent = [ Int] ( 0 ..< s. count)
5+ var count = [ Int] ( repeating: 1 , count: s. count)
86
9- var maxLength = 0
10- var lastIndex = 0
7+ var maxLengthIndex = 0
8+ var maxLength = 1
119
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]가 옴
10+ for i in stride ( from: 1 , to: s. count, by: 1 ) {
11+ for j in stride ( from: 0 , to: i, by: 1 ) {
12+ if s [ j] < s [ i] , count [ j] + 1 > count [ i] {
13+ count [ i] = count [ j] + 1
14+ parent [ i] = j
15+ if count [ i] > maxLength {
16+ maxLength = count [ i]
17+ maxLengthIndex = i
2218 }
2319 }
2420 }
25- // 현재까지의 최대 길이와 해당 길이의 마지막 인덱스 갱신
26- if dp [ i] > maxLength {
27- maxLength = dp [ i]
28- lastIndex = i
29- }
3021}
3122
32- // LIS 구성
3323var 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- }
24+ var i = maxLengthIndex
4225
26+ while parent [ i] != i {
27+ answer. append ( s [ i] )
28+ i = parent [ i]
29+ }
4330
31+ answer. append ( s [ i] )
4432print ( maxLength)
45- print ( answer. reversed ( ) . map { " \( $0) " } . joined ( separator: " " ) )
33+ print ( answer. reversed ( ) . map { " \( $0) " } . joined ( separator: " " ) )
0 commit comments