[백준] 18427: 함께 블록 쌓기 - JAVA

https://www.acmicpc.net/problem/18427

풀이

N명의 학생이 들고있는 블럭을 인 당 최대 한 개 사용하여 높이 H를 정확하게 맞출 수 있는 경우의 수를 구해야한다.

dp배열을 2차원으로 만들었다. new int[n + 1][h + 1]

1번 학생부터 시작하여 1~h까지 높이에 대해 경우의 수를 구한다.

n번 학생이 특정 높이 h에 대해 만들 수 있는 경우의 수는 다음과 같이 구할 수 있다.

(n번 학생이 들고 있는 h 높이의 블록의 수) + (n-1번 학생까지 했을 때 h 높이를 만든 경우의 수) + (n번 학생이 가진 a 높이의 블록 + n-1번 학생까지 했을 때 h-a 높이를 만든 경우의 수)

이 방법을 코드로 옮기면 다음과 같다.

for (int i = 1; i < n + 1; i++) {
    dp[i - 1][0] = 1;
    for (int j = 1; j < h + 1; j++) {
        for (int height : list.get(i)) {
            if (j >= height) {
                dp[i][j] += dp[i - 1][j - height];
            }
        }
        dp[i][j] += dp[i - 1][j];
    }
}

이전 번호의 높이 0의 값을 1로 초기화 해주고 진행한다.

높이 h인 블럭이 있다면 dp[i-1][j-h]의 값을 더해준다.


메모리: 17540KB

시간: 204ms

언어: Java 11

코드

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int h = Integer.parseInt(st.nextToken());

        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        for (int i = 0; i < n + 1; i++) {
            list.add(new ArrayList<>());
        }
        for (int i = 1; i < n + 1; i++) {
            st = new StringTokenizer(br.readLine());
            while (st.hasMoreTokens()) {
                list.get(i).add(Integer.parseInt(st.nextToken()));
            }
        }

        int[][] dp = new int[n + 1][h + 1];

        for (int i = 1; i < n + 1; i++) {
            dp[i - 1][0] = 1;
            for (int j = 1; j < h + 1; j++) {
                for (int height : list.get(i)) {
                    if (j >= height) {
                        dp[i][j] += dp[i - 1][j - height];
                        dp[i][j] %= 10007;
                    }
                }
                dp[i][j] += dp[i - 1][j];
                dp[i][j] %= 10007;
            }
        }

        System.out.println(dp[n][h]);
    }

}