https://www.acmicpc.net/problem/14002
14002번: 가장 긴 증가하는 부분 수열 4
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
문제
풀이
이전에 포스팅했던 LIS 알고리즘에 + 추척 까지 해줘야 하는 문제이다.
(이전 포스팅 참고 : https://katastrophe.tistory.com/39?category=956141 )
1. DP 풀이
최종적으로 나온 부분 수열의 길이 값을 ans 라고 하면
각 구간마다 길이를 저장해놓은 DP배열의 맨 끝에서부터 추적하면 된다.
1
2
3
4
5
6
7
8
9
|
Stack<Integer> result = new Stack<>();
for(int i=N-1;i>=0;i--){
if(dp[i]==ans){
result.push(list.get(i));
ans--;
}
}
while (!result.isEmpty())
System.out.print(result.pop()+" ");
|
cs |
최종 코드
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
|
import java.util.*;
import java.io.*;
import java.util.stream.Collectors;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] dp = new int[N];
List<Integer> list = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
Arrays.fill(dp,1);
for(int i=0;i<N;i++)
for(int j=0;j<i;j++)
if(list.get(i) > list.get(j)) dp[i] = Math.max(dp[i],dp[j]+1);
int ans = Arrays.stream(dp).max().getAsInt();
System.out.println(ans);
Stack<Integer> result = new Stack<>();
for(int i=N-1;i>=0;i--){
if(dp[i]==ans){
result.push(list.get(i));
ans--;
}
}
while (!result.isEmpty())
System.out.print(result.pop()+" ");
}
}
|
cs |
2. 이진탐색 풀이
경로를 저장할 때 저장될 수의 (위치, 값) 을 리스트에 하나씩 넣고, 제일 큰 위치로부터 역추적 하였다.
마지막 출력 원리는 처음엔 Stack을 썻지만 , 원리가 같은 StringBuilder의 insert를 사용했다.
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
49
50
|
import java.util.*;
import java.io.*;
import java.util.stream.Collectors;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder answer = new StringBuilder();
int N = Integer.parseInt(br.readLine());
List<Integer> list = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
ArrayList<Integer> result = new ArrayList<>();
ArrayList<Node> path = new ArrayList<>();
result.add(list.get(0)); path.add(new Node(0,list.get(0)));
int maxIndex=0;
for(int i=1;i<N;i++){
int next=list.get(i);
int pos;
if(result.get(result.size()-1) < next) {
result.add(next);
pos = result.size()-1;
}
else{
pos = Collections.binarySearch(result, next);
if(pos < 0) pos = -pos-1;
result.set(pos,next);
}
path.add(new Node(pos,next));
maxIndex = Math.max(pos,maxIndex);
}
for(int i=path.size()-1;i>=0;i--) {
if(path.get(i).index == maxIndex) {
answer.insert(0, path.get(i).value + " ");
maxIndex--;
}
}
answer.insert(0,result.size()+"\n");
System.out.print(answer);
}
static class Node{
int index;
int value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
}
}
|
cs |
'알고리즘,PS > 백준' 카테고리의 다른 글
[BOJ] 백준 [9252] LCS 2 JAVA (0) | 2021.09.29 |
---|---|
[BOJ] 백준 [1005] ACM Craft JAVA (0) | 2021.09.28 |
[BOJ] 백준 [1365] 꼬인 전깃줄 JAVA (0) | 2021.09.24 |
[BOJ] 백준 [11722] 가장 긴 감소하는 부분수열 JAVA (0) | 2021.09.23 |
[BOJ] 백준 [12865] 평범한 배낭 JAVA (0) | 2021.09.22 |