풀이방법
2022.01.26
입력값으로 n개의 정수 배열이 주어진다.
이 정수 배열을 nums라 부르자.
길이가 n인 정수 배열 dp를 만든다.
dp[i] 는 nums[i]를 마지막 순서로 갖는 가장 긴 증가하는 배열의 길이이다.
예를 들어, 아래의 표를 보자.
nums | 10 | 20 | 10 | 30 | 20 | 50 |
dp | 1 | 2 | 1 | 3 | 2 | 4 |
nums[0]의 값은 10이다.
10으로 끝나는 가장 긴 증가하는 배열은 {10}이다.
{10}의 길이는 1이다.
따라서 dp[0]은 1이다.
nums[3]의 값은 30이다.
30으로 끝나는 가장 긴 증가하는 배열은 {10, 20, 30}이다.
{10, 20, 30}의 길이는 3이다.
따라서 dp[3]은 3이다.
이를 코드로 구현한 뒤에 dp 배열의 요소 중 가장 큰 것을 화면에 출력하면 문제가 해결된다.
dp[i]를 구하는 방법은 다음과 같다.
nums[0] ~ nums[i-1]을 탐색하며 nums[i]보다 값이 작은 것들을 찾는다.
이렇게 찾은 값들 중 가장 큰 것의 dp값에 1을 더하면
dp[i]값과 같다.
예를 들어 위 표에서 30과 50의 경우를 보자.
{10, 20, 30}이 있기 때문에 dp[3]은 3이다. 이를 이용해 dp[5]를 구할 수 있다.
30<50이다. 그리고 50보다 앞에 있는 수 중 30이 가장 크다.
그럼 50으로 끝나는 가장 긴 증가수열은
{10, 20, 30}
의 마지막에 50을 덧붙인
{10, 20, 30, 50}
이다.
이러한 성질을 이용하여,
dp[3]+1 = dp[5]임을 알 수 있다.
※nums의 값이 가장 크면 dp의 값도 반드시 가장 크기 때문에,
나는 가장 큰 nums값이 아니라 가장 큰 dp값을 찾아 거기에 1을 더하였다.
코드
Java(2022.01.26)
import java.io.*;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//n 읽어오기
int n = Integer.parseInt(br.readLine());
//정수 배열 읽어오기
String[] input = br.readLine().split(" ");
int[] nums = new int[n];
for(int i = 0; i<n; i++) {
nums[i] = Integer.parseInt(input[i]);
}
int[] dp = new int[n];
dp[0] = 1;
for(int i= 1; i<n; i++) {
dp[i] = 1; //가능한 가장 작은 dp값인 1로 초기화
for(int j = 0; j<i; j++) {
//자신보다 앞순서에서,
//(숫자값)이 자신보다 작은 동시에 (dp값+1)이 자신보다 큰 경우를 발견하면,
//해당 (dp값+1)을 취한다.
if(nums[j]<nums[i] && dp[i]<dp[j]+1) {
dp[i] = dp[j]+1;
}
}
}
//dp 중 가장 큰 값을 구하여 출력
Arrays.sort(dp);
System.out.print(dp[n-1]);
}
}
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
#1448 : 삼각형 만들기 (0) | 2022.01.28 |
---|---|
#18870 : 좌표 압축 (0) | 2022.01.28 |
#11047 : 동전 0 (0) | 2022.01.24 |
#2747 : 피보나치 수 (0) | 2022.01.22 |
#11048 : 이동하기 (0) | 2022.01.22 |