Algorithm
[백준] 11054 - 가장 긴 바이토닉 부분 수열(Java)
코드파고
2025. 3. 11. 11:10
문제 파악
https://www.acmicpc.net/problem/11054
풀이
DP문제이며 푸는데 오래 걸리지는 않았으나,
문제에서 놓친 부분이 있어 마지막에 정답을 계산하는 과정에서 조금 헤맸다. 문제를 잘 읽도록 하자 ^_^
가장 먼저 오름차순, 내림차순의 길이를 저장하는 DP 배열을 각각 선언해 준다.
DP는 "해당 자리의 숫자를 포함"하여 오름차순, 내림차순을 만족하는 수열의 길이를 저장한다.
증가(혹은 감소) 수열을 만족했을 때 DP값에서 1을 더해 현재 DP에 저장하도록 하자.
오름차순은 인덱스가 증가하는 방향으로, 내림차순은 감소하는 방향으로 순회하도록 했다.
다음 {1,2,2,3,1,4} 수열을 예로 들어 보았다.
마지막으로 정답은 각각의 자리의 오름차순, 내림차순 DP를 더해 준 다음 1을 빼 준 값이 된다.
1을 빼주는 이유는 오름차순 DP, 내림차순 DP 모두 현재 위치의 원소를 포함하기에 중복을 제거해주는 과정이다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(br.readLine());
int[] input = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int[] ascDP = new int[count];
int[] descDP = new int[count];
Arrays.fill(ascDP, 1);
Arrays.fill(descDP, 1);
// asc
for (int i = 0; i < count; i++) {
for (int j = 0; j < i; j++) {
if (input[i] > input[j]) {
ascDP[i] = Math.max(ascDP[i], ascDP[j] + 1);
}
}
}
// desc
for (int i = count - 1; i >= 0; i--) {
for (int j = i + 1; j < count; j++) {
if (input[i] > input[j]) {
descDP[i] = Math.max(descDP[i], descDP[j] + 1);
}
}
}
System.out.println(IntStream.range(0, count)
.map(i -> descDP[i] + ascDP[i] - 1).max().orElse(1));
}
}