https://www.acmicpc.net/problem/11053
11053번: 가장 긴 증가하는 부분 수열
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
DP문제로서 작은것부터 커지는 Botton-Up 방식을 사용해보자
주어진 입력의 배열은 다음과 같다
arr[0] | arr[1] | arr[2] | arr[3] | arr[4] | arr[5] |
10 | 20 | 10 | 30 | 20 | 50 |
만약 arr 이 arr[0] 까지 있다면 {10} 으로 최대 길이는 1 (dp[0]=1)
거꾸로 가며(<-) 기준 수보다 작은 수를 찾아가며 길이에 + 1을 해주고 길이 중 최댓값을 dp배열에 넣는다.
dp[0] |
1 |
arr[1] : arr[1] > arr[0] => dp[0] + 1 하여 길이는 2 (dp[1]=2)
dp[0] | dp[1] |
1 | 2 |
arr[2] : arr[2] < arr[1] => 패스, arr[2] == arr[0] => 패스, 길이는 1 (dp[2]=1)
dp[0] | dp[1] | dp[2] |
1 | 2 | 1 |
arr[3] : arr[3] > arr[2] => dp[2] + 1 = 2, arr[3] > arr[1] => dp[1] + 1 = 3,
arr[3] > arr[0] => dp[0] + 1 = 2
따라서 최대길이는 3 (dp[3]=3)
dp[0] | dp[1] | dp[2] | dp[3] |
1 | 2 | 1 | 3 |
arr[4] < arr[3] => 패스, arr[4] > arr[2] => dp[2] + 1 = 2,
arr[4] == arr[1] => 패스, arr[4] > arr[0] => dp[0] + 1 = 2
따라서 최대길이는 2
dp[0] | dp[1] | dp[2] | dp[3] | dp[4] |
1 | 2 | 1 | 3 | 2 |
arr[5] > arr[4] => dp[4] + 1 = 3, arr[5] > arr[3] => dp[3] + 1 = 4,
arr[5] > arr[2] => dp[2] + 1 = 2, arr[5] > arr[1] => dp[1] + 1 = 3,
arr[5] > arr[4] => dp[4] + 1 = 3
따라서 최대길이는 4
dp[0] | dp[1] | dp[2] | dp[3] | dp[4] | dp[5] |
1 | 2 | 1 | 3 | 2 | 4 |
실제로 {10,20,30,50} 이므로 최대길이 4를 만족하는 배열 dp를 위와 같은 방식으로 구하였다.
아래는 dp방식(Bottom-Up) 방식으로 구현한 코드이다.
public static int dp(int[] arr) {
int result = 0;
int[] dp = new int[arr.length];
resulr = dp[0] = 1; // arr 크기가 1일 경우를 대비하기위해 dp 최솟값 초기화
for(int i = 1; i < arr.length; 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;
result = Math.max(result, dp[i]);
}
return result;
}
반복문을 수행하여 i 인덱스를 기준으로 삼은 배열을 거꾸로 인덱스를 감소시켜가며 크기를 비교한다
만약 크거나 같을경우 무시하고 작은 경우에만 최댓값을 해당 비교 인덱스 배열의 최대길이로 셋팅한다.
이 경우 비교 인덱스의 최대길이보다 이미 최댓값이 클 경우 도 조건을 만족시켜줘야한다.
만약 배열의 크기가 1일 경우 result 값을 계산하는 반복문을 수행하지 않으므로 최초 초기화를 해줘야한다.
아래는 전체 소스코드이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int A = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] arr = new int[A];
for(int i = 0; i < A; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
System.out.println(dp(arr));
}
public static int dp(int[] arr) {
int result = 0;
int[] dp = new int[arr.length];
dp[0] = 1;
for(int i = 1; i < arr.length; 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;
result = Math.max(result, dp[i]);
}
return result;
}
}
'PS > BOJ' 카테고리의 다른 글
백준 2145 숫자 놀이 / JAVA (0) | 2023.03.25 |
---|---|
백준 1408 24 / JAVA (0) | 2023.03.20 |
백준 1012 유기농배추(DFS,BFS) / JAVA (0) | 2023.02.03 |
백준 2667 단지번호붙이기(DFS,BFS) / JAVA (0) | 2023.02.01 |
백준 2178 미로탐색 / JAVA (0) | 2023.01.31 |
댓글