• [백준 알고리즘] (DP) 11053번 Java 풀이

    2020. 3. 26.

    by. SDev

    728x90

    DP - 1463, 11726, 11727, 9095, 10844, 11057, 2193, 9465, 2156, 11053, 11055, 11722, 11054, 1912, 2579, 1699, 2133, 9461, 2225, 2011, 11052

    출처: https://plzrun.tistory.com/entry/알고리즘-문제풀이PS-시작하기 [plzrun's algorithm]

     

    백준 알고리즘 11053번

     

    <첫 번째 오답 풀이>

    DP문제라는걸 알고 접근했음에도 불구하고 이게 왜 DP로 풀어야되는지 헷갈렸다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package dp;
     
    import java.util.Scanner;
     
    public class N11053 {
     
        static int array[];
        public static void main(String[] args) {
     
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            array = new int[n];
            
            for(int i=0; i<n; i++) {
                array[i] = sc.nextInt();
            }
            sc.close();
            int temp=0;
            int max=0;
            
            for(int i=0; i<n; i++) {
                if(max<array[i]) {
                    temp++;
                    max= array[i];
                }
            }
            System.out.println(temp);
        }
     
    }
    Colored by Color Scripter
     

     

    풀이가 아주 귀엽고 간단한데...

    int max와 int temp를 생성하고 이들을 0으로 정의해준뒤,
    max에 차례대로 수열의 값을 비교해가며 최댓값을 max에 계속해서 갱신해준다.
    그리고 temp에는 수열의 처음부터 끝까지 max가 몇번 갱신되었는지를 기록한다.

    이렇게 풀이를 하면 주어지는 예제 입력 {10, 20, 10, 30, 20, 50}은 
    정답인 4를 잘 출력하는데...

    역시나 이렇게 쉬울리가 없을 뿐더러 DP도 아니다.

    그 이유는 다음과 같다.
    만약 {10, 50, 20, 30, 40}이라는 수열이 입력된다면?
    max=50에서 수열의 끝까지 더이상 갱신되지 않으며, temp=2로 출력값은 2일 것이다.
    그러나 이 케이스는 10, 20, 30, 40이 가장 긴 부분 수열이므로 바른 출력값은 4이다.

    그래서 다시 다른 사람들의 풀이를 참고했다..^^;

     

    <정답 풀이>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package dp;
     
    import java.util.Scanner;
     
    public class N11053 {
     
        public static void main(String[] args) {
     
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int array[] = new int[n+1];
            int dp[] = new int[n+1];
            
            for(int i=1; i<n+1; i++) {
                array[i] = sc.nextInt();
            }
            sc.close();
            
            dp[1]=1;
            
            for(int i=2; i<=n; i++) {
                dp[i] =1;
                for(int j=1; j<i;j++) {
                    if(array[i]>array[j] &&dp[i] <=dp[j]) {
                        dp[i] = dp[j]+1;
                    }
                }
            }
            int max = 0;
            for(int i=1; i<=n; i++) {
                max = Math.max(dp[i], max);
            }
            System.out.println(max);
        }
     
    }
     
    Colored by Color Scripter
     

     

    먼저 개인적으로 가장 많이 참고했고 보기 쉬웠던 접근법을 올려주신 분이 아주 설명을 잘 해주셨다.

    https://developer-mac.tistory.com/71

     

    나는 24라인~26라인이 조금 헷갈렸는데
    24라인의 경우, j가 증가하면서 차례대로 앞에서부터 array[i]와 비교하는건 알겠는데,
    dp[i]와 dp[j]는 왜 비교하는건지 궁금했다.

    이는 이러한 경우 때문이다.
    주어진 예제입력 {10, 20, 10, 30, 20, 50}을 보면,

    잘라서 30까지만 봐도 24라인에서 만약 dp간의 비교조건이 없다면 i=4이고,  j=3인 경우에,
    25라인 dp[4]는 dp[3]+1이 적용되어 dp[4]에 2가 들어간다.
    따라서 Array[i], Array[j] 비교만아니라 dp[i], dp[j]도 함께 비교해주는 것이다.

    또한, 참고한 분의 풀이에서는 Array[i] = Array[j]일때, dp도 같게 해주는데,
    그 부분은 없어도 문제 없이 돌아간다.
    (궁금해서 왜 있는지 반례 찾아보다가 빼고 제출해봤는데 정답 받음!)

     

     

     

    Github: https://github.com/jaeuk9407/AlgorithmBOJ

     

    jaeuk9407/AlgorithmBOJ

    BaekJoon Online Judge Problems. Contribute to jaeuk9407/AlgorithmBOJ development by creating an account on GitHub.

    github.com

     

    댓글