Algorithm & Data Structures/BOJ

b2629. 양팔저울

Geisha 2025. 1. 17. 16:21

 

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

 

 

 

문제를 풀기 위해서는 dp[][] 의 규칙을 아는것이 가장 편하다.

이 문제의 규칙은 다음과 같다. 

 

1. dp[i][j] 는 boolean[N][M] 으로써 i 번째 추까지 사용했을 때 j무게를 확인할 수

있는가 없는가를 나타낸다. 또한 N은 추의갯수 M은 가능한 무게측정범위 즉 15001이 된다.

 

2. dp[i-1][j] 가 true라면 dp[i][j] 또한 true이다.

 

3. dp[i-1][ K ] 에서 true가 된다면

dp[i][K-i번째 추의 절댓값]과

dp[i][K+i번째 추의 절댓값]은 15001을 넘지않으면 true이다.

 

위의 규칙을 활용하여 나는 init method를 통해 초기화 및 입력을 받았으며

logic에서 N번째 추를 15000번 루프를 돌아 확인하고

true check를 통해서 풀이하였다.

 

 

 

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    static int N,M;
    static int[] beads,weights;
    static boolean[][] dp;

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        init(br);
        logic();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < M ; i++) {
            if (beads[i] > 15000) sb.append("N ");
            else if(dp[N-1][beads[i]]) sb.append("Y ");
            else sb.append("N ");
        }
        System.out.println(sb);
    }

    private static void logic() {
        Arrays.sort(weights);
        dp[0][weights[0]]= true;
        for (int i = 1; i < N; i++) { //구슬 종류
            dp[i][weights[i]]= true;
            for(int j = 0 ; j < 15001; j++) { // 이전 무게 위치
                if(dp[i-1][j]) {
                    dp[i][j] = true;
                    int sum = Math.abs(j + weights[i]);
                    dp[i][Math.abs(j - weights[i])] = true;
                    if (sum <= 15000)
                        dp[i][sum] = true;
                }
            }
        }
    }

    private static void init(BufferedReader br) throws IOException {
        N = Integer.parseInt(br.readLine());
        weights = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++)
            weights[i] = Integer.parseInt(st.nextToken());

        M = Integer.parseInt(br.readLine());
        beads = new int[M];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < M; i++)
            beads[i] = Integer.parseInt(st.nextToken());

        dp = new boolean[N][15001];
    }
}