[백준] 14003번: 가장 긴 증가하는 부분 수열 5
[백준] 14003번: 가장 긴 증가하는 부분 수열 5
📌 문제
https://www.acmicpc.net/problem/14003
📌 설명
이분탐색을 통해 LIS의 길이 및 LIS를 구하는 방법을 알아야 한다.
먼저 LIS의 길이를 구하기 위해 임의의 벡터 tmp를 선언한다. 입력받은 배열 각각에 대하여 tmp에 들어갈 곳을 이분 탐색을 통해 찾는다. 만약 찾을 수 없다면 tmp에 값을 삽입하고, 찾았다면 해당 위치의 tmp의 값을 v[i]로 대체한다. tmp의 길이가 곧 LIS의 길이이다. 단, tmp에 저장된 배열의 값들을 실제 LIS와 다를 수 있다.
따라서 실제 LIS를 따로 구해야 한다. v[i]가 tmp에 삽입된 위치를 저장하는 배열 lis_idx를 선언한다. lis_idx를 역추적하여 얻은 수열이 LIS이다.
📌 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <vector>
using namespace std;
vector<int> tmp; // LIS의 길이를 구하는 데 사용
int lis_idx[1000000];
int main() {
int n;
cin >> n;
vector<int> v;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
v.push_back(x);
}
for (int i = 0; i < n; i++) {
int idx = lower_bound(tmp.begin(), tmp.end(), v[i]) - tmp.begin();
if (idx == tmp.size()) {
tmp.push_back(v[i]);
}
else {
tmp[idx] = v[i];
}
lis_idx[i] = idx;
}
cout << tmp.size() << "\n";
// LIS에 해당하는 수의 인덱스 역추적
int cur = tmp.size() - 1;
vector<int> rev_lis;
for (int i = n - 1; i >= 0; i--) {
if (lis_idx[i] == cur) {
rev_lis.push_back(v[i]);
cur--;
}
}
for (int i = tmp.size() - 1; i >= 0; i--) {
cout << rev_lis[i] << " ";
}
}
This post is licensed under CC BY 4.0 by the author.