sm 기술 블로그
137. 11054(가장 긴 바이토닉 부분 수열) 본문
import java.util.*;
import java.io.*;
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[] num = new int[N];
int[] numReverse = new int[N];
int[] numDpIncrease = new int[N];
int[] numDpDecrease = new int[N];
int[] result = new int[N];
String[] tmp = br.readLine().split(" ");
for (int i = 0; i < N; i++) {
num[i] = Integer.parseInt(tmp[i]);
numReverse[N - i - 1] = num[i];
numDpIncrease[i] = 1;
numDpDecrease[i] = 1;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < i; j++) {
if (num[i] > num[j]) {
numDpIncrease[i] = Math.max(numDpIncrease[i], numDpIncrease[j] + 1);
}
if (numReverse[i] > numReverse[j]) {
numDpDecrease[i] = Math.max(numDpDecrease[i], numDpDecrease[j] + 1);
}
}
}
for (int i = 0; i < N; i++) {
result[i] = numDpIncrease[i] + numDpDecrease[N-i-1] - 1;
}
Arrays.sort(result);
System.out.println(result[result.length-1]);
}
}
문제요약
가장 긴 바이토닉 부분 수열은?
S1 < S2 < ... Sk-1 < Sk > Sk+1 > ... SN-1 > SN을 만족한다면, 그 수열을 바이토닉 수열
설명
문제에 힌트가 있다.
S1 < S2 < ... Sk-1 < Sk 이 부분과
Sk > Sk+1 > ... SN-1 > SN 이 부분을 따로 생각해보자.
S1 < S2 < ... Sk-1 < Sk 이 부분은 0번째 인덱스 부터 증가하는 수열,
Sk > Sk+1 > ... SN-1 > SN 아 부분은 N번째 인덱스 부터 증가하는 수열.
따라서
다음과 같이 입력값 | 입력값을 뒤집은 값을 나눈다.
수열을 진행하면서 해당 인덱스에서 가장 큰 길이를 가질 수 있는 것을 각각 정의해준다.
nomal에 해당 인덱스를 뒤집었기 때문에.
nomal[index] + reverse[N - index -1] 를 해준다면 1번과 2번을 합친 것이된다.
단, index 부분은 두 번 중복으로 수열을 처리했기 때문에 마지막에 -1을 해줘야 한다.
int N = Integer.parseInt(br.readLine());
int[] num = new int[N];
int[] numReverse = new int[N];
int[] numDpIncrease = new int[N];
int[] numDpDecrease = new int[N];
int[] result = new int[N];
String[] tmp = br.readLine().split(" ");
for (int i = 0; i < N; i++) {
num[i] = Integer.parseInt(tmp[i]);
numReverse[N - i - 1] = num[i];
numDpIncrease[i] = 1;
numDpDecrease[i] = 1;
}
초기설정이다.
한번에 반복문으로 모두 처리 가능하다.
for (int i = 0; i < N; i++) {
for (int j = 0; j < i; j++) {
if (num[i] > num[j]) {
numDpIncrease[i] = Math.max(numDpIncrease[i], numDpIncrease[j] + 1);
}
if (numReverse[i] > numReverse[j]) {
numDpDecrease[i] = Math.max(numDpDecrease[i], numDpDecrease[j] + 1);
}
}
}
원래 배열, 뒤집은 배열에 해당 인덱스에 각각 가장 긴 수열을 계산해 주었다.
for (int i = 0; i < N; i++) {
result[i] = numDpIncrease[i] + numDpDecrease[N-i-1] - 1;
}
원래 값과 뒤집은 값을 더해 result를 에 저장해준다. 단, 계산과정 중 중복으로 처리한 부분이 있어 -1을 해준다.
'문제 > 백준_자바' 카테고리의 다른 글
139. 9251(LCS) (0) | 2022.07.10 |
---|---|
138. 2565(전깃줄) (0) | 2022.07.10 |
136. 11053(가장 긴 증가하는 부분 수열) (0) | 2022.07.08 |
135. 2156(포도주 시식) (0) | 2022.07.08 |
134. 10844(쉬운 계단 수) (0) | 2022.07.06 |
Comments