ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 11052 카드 구매하기 동적계획법 활용 2가지 풀이 ( Java )
    Problem Solving/Java 2019. 10. 25. 20:12
    반응형
     

    11052번: 카드 구매하기

    첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)

    www.acmicpc.net

     

    - Bottom-up 방식

     

    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
    40
    41
    42
    43
    44
    import java.io.*;
     
    public class Main {
     
        public static void main(String[] args) throws IOException {
     
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
     
            int n = Integer.parseInt(br.readLine());
            // 구매해야하는 카드 갯수
     
            String[] temp = br.readLine().split(" ");
            int[] prices = new int[n + 1];
            // 가격 저장할 배열
     
            for (int i = 0; i < n; i++) {
                prices[i + 1= Integer.parseInt(temp[i]);
                // String to int
            }
     
            int[] d = new int[n + 1];
            // d[i] = n개의 카드를 구매하기 위해 지불해야 하는 금액의 최대값
            // 이는 i개가 들어있는 카드팩을 샀을 때 사용한 금액 + n-i개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최대값과 같다 
            
            // d[i] =  d[n-i] + prices[i] 
            
            for (int i = 1; i <= n; i++) {
                // 1개를 구매해야할 때부터 n개를 구매해야 할 때 까지
                for (int j = 1; j <= i; j++) {
                    // n개 짜리 n-1] 
                    if(d[i] < d[i-j] + prices[j]) {
                         
                        d[i] = d[i-j] + prices[j];
                    }
                }
            }
     
            bw.write(String.valueOf(d[n]));
            bw.flush();
     
        }
     
    }

     

    - Top-Down 방식

     

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    import java.io.*;
     
    public class Main {
     
        public static int[] d;
        public static int[] prices;
     
        public static int buyCard(int n) {
     
            if (d[n] > 0) {
                return d[n];
                // 메모한 값이 있다면 사용
            }
     
            if (n == 1) {
                // 하나 살 때
                d[n] = prices[n];
                // 최대 가격은 prices[1] 이다
                return d[n];
            }
            // 이걸 기저 사례로 세팅
     
            for (int i = 1; i <= n; i++) {
                // n개 살 때 1개 들어있는 카드팩 + 나머지를 구매했을 때 부터 
                // n개 들어있는 카드팩 하나만 구매했을 때까지 
                d[n] = buyCard(n - i) + prices[i] > d[n] ? d[n - i] + prices[i] : d[n];
                //     반복하며 재귀를 내려 보내고
                // 가장 큰 걸 d[n]의 값으로 저장
            }
     
            return d[n];
        }
     
        public static void main(String[] args) throws IOException {
     
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
     
            int n = Integer.parseInt(br.readLine());
            // 구매해야하는 카드 갯수
     
            String[] temp = br.readLine().split(" ");
            prices = new int[n + 1];
            // 가격 저장할 배열
     
            for (int i = 0; i < n; i++) {
                prices[i + 1= Integer.parseInt(temp[i]);
                // String to int
            }
     
            d = new int[n + 1];
            // d[i] = n개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최대값
            // 이는 i개가 들어있는 카드팩을 샀을 때 사용한 금액 + n-i개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최대값과 같다
     
            // d[i] = d[n-i] + prices[i]
     
            int answer = buyCard(n);
     
            bw.write(String.valueOf(answer));
            bw.flush();
     
        }
     
    }

     

    배열이 두개 필요하고 재귀에서 반복문을 써야하니까

    분명 감을 잡아간다고 생각했는데 Top-Down 방식으로 구현할 때 엄청 헤맸다

    반응형

    댓글

Designed by Tistory.