라이브러리는 도서관 아닌가요

백준 (BOJ) 17213 과일 서리 java dp 본문

알고리즘 문제

백준 (BOJ) 17213 과일 서리 java dp

veryhi 2022. 6. 10. 14:15

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

 

17213번: 과일 서리

민건이네 과일 농장은 N가지 종류의 과일을 재배하는 중이다. 평소 민건이에게 앙심을 품고 있던 지환이는 민건이를 골탕 먹이기 위하여 민건이네 과일 농장에서 과일들을 훔치기로 다짐했다.

www.acmicpc.net

 

중복 조합과 dp의 콜라보

 

N개의 자리를,

 

N개를 뺀 M개(과일이 최소 하나씩 필요하므로)에 할당하는 문제.

 

(n) H (m-n) = (n+(m-n)-1) C (m-n) = (m-1) C (m-n) = (m-1) C (n-1)

 

연산량을 줄이기 위해 계산 시작 전에 판별식을 넣었다.

 

채점 속도 차이는 없는 듯 하다.

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());

        long up = 1;
        long down = 1;

        int mMinus1 = M-1;
        int nMinus1 = N-1;

        if(nMinus1 < mMinus1){
            int count = nMinus1;
            int i = mMinus1;
            while (count != 0){
                up *= i;
                --i;
                --count;
            }

            for(i=1; i<=nMinus1; i++) {
                down*= i;
            }
        }
        else{
            int count = M-N;
            int i = mMinus1;
            while (count != 0){
                up *= i;
                --i;
                --count;
            }

            for(i=1; i<=M-N; i++) {
                down*= i;
            }
        }

        System.out.print(up/down);

    }
}

 

 

 

처음에 독특하게 접근해서 풀이한 방식

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());

        if(N == 1){
            System.out.print(1);
            return;
        }
        int rowNum = M - N + 1;
        int nOfCombination = N - 1;
        long[] dp = new long[rowNum];
        dp[0] = 1;
        for(int rOfCombination=1; rOfCombination<rowNum; ++rOfCombination){
            // bigger num check
            int nMinus1 = nOfCombination - 1;
            long combRst;

            // n-1+r C r == n-1+r C n-1
            if(nMinus1 < rOfCombination){
                combRst = combination(nMinus1 + rOfCombination, nMinus1);
            }
            else{
                combRst = combination(nMinus1 + rOfCombination, rOfCombination);
            }

            dp[rOfCombination] = dp[rOfCombination-1] + combRst;
        }

        System.out.print(dp[rowNum-1]);
    }

    static long factorial(int num){
        long rst = 1;
        for(; 0<num; --num){
            rst *= num;
        }
        return rst;
    }

    static long combination(int n, int r){
        long rst = 1;

        // i == 반복 횟수
        int i = r;
        while (i != 0){
            rst *= n;
            --n;
            --i;
        }

        return rst / factorial(r);
    }
}

 

 

Comments