https://www.acmicpc.net/problem/11054
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main{
public static void LIS(int arr[], int dp[], int n){
for(int i=1; i<n; i++){
int max = 0;
for(int j=i-1; j>=0; j--){
if(arr[i] > arr[j] && dp[j] > max) max = dp[j];
}
dp[i] = max +1;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
int[] reverse_arr = new int[n];
int[] up_dp = new int[n];
int[] down_dp = new int[n];
up_dp[0] = 1;
down_dp[0] = 1;
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=0; i<n; i++){
arr[i] = reverse_arr[n-i-1] = Integer.parseInt(st.nextToken());
}
LIS(arr, up_dp, n);
LIS(reverse_arr, down_dp, n);
int answer = 1;
for(int i=0; i<n; i++){
up_dp[i]+=down_dp[n-i-1]-1;
answer = Math.max(answer, up_dp[i]);
}
System.out.println(answer);
}
}
arr[i]에 대하여 그 앞의 숫자들은 오름차순이 되어야하고, 그 뒤에 숫자들은 내림차순이 되는 가장 긴 부분 수열을 찾아야한다.
이전 부분 수열 문제들에 비해 쉽지 않아 고민하다가
arr[i]이전 오름차순 수열의 최대 길이 dp 따로, arr[i] 이후 내림차순 수열의 최대 길이 dp 따로 구해 둘을 합한 후 -1 (자기자신 겹치는 것) 을 해주기로 했다.
dp[i] 는 i번째 숫자를 마지막으로 하는 가장 긴 증가사는 부분 수열의 길이,
down_dp[i]는 i번째 숫자를 시작으로 하는 가장 긴 감소하는 부분 수열의 길이로 정의한다.
https://yeoncoding.tistory.com/597
'ALGORITHM' 카테고리의 다른 글
[JAVA] 알고리즘 : 동적 계획법- 동전교환(냅색 알고리즘) (0) | 2022.11.09 |
---|---|
[JAVA] 백준 9465번- 스티커 (0) | 2022.11.08 |
[JAVA] 백준 11722번- 가장 긴 감소하는 부분 수열 (0) | 2022.11.07 |
[JAVA] 백준 11055번- 가장 큰 증가 부분 수열 (0) | 2022.11.07 |
[JAVA] 백준 11057번- 오르막 수 (0) | 2022.11.06 |