πŸ“– [λ°±μ€€μ•Œκ³ λ¦¬μ¦˜ 풀이] Q.1010 닀리 놓기 문제 풀이 - java

πŸ“– 문제

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

μž¬μ›μ΄λŠ” ν•œ λ„μ‹œμ˜ μ‹œμž₯이 λ˜μ—ˆλ‹€. 이 λ„μ‹œμ—λŠ” λ„μ‹œλ₯Ό 동μͺ½κ³Ό μ„œμͺ½μœΌλ‘œ λ‚˜λˆ„λŠ” 큰 일직선 λͺ¨μ–‘μ˜ 강이 흐λ₯΄κ³  μžˆλ‹€.

ν•˜μ§€λ§Œ μž¬μ›μ΄λŠ” 닀리가 μ—†μ–΄μ„œ μ‹œλ―Όλ“€μ΄ 강을 κ±΄λ„ˆλŠ”λ° 큰 λΆˆνŽΈμ„ κ²ͺκ³  μžˆμŒμ„ μ•Œκ³  닀리λ₯Ό μ§“κΈ°λ‘œ κ²°μ‹¬ν•˜μ˜€λ‹€.

κ°• μ£Όλ³€μ—μ„œ 닀리λ₯Ό 짓기에 μ ν•©ν•œ 곳을 μ‚¬μ΄νŠΈλΌκ³  ν•œλ‹€. μž¬μ›μ΄λŠ” κ°• 주변을 λ©΄λ°€νžˆ 쑰사해 λ³Έ κ²°κ³Ό κ°•μ˜

μ„œμͺ½μ—λŠ” N개의 μ‚¬μ΄νŠΈκ°€ 있고 동μͺ½μ—λŠ” M개의 μ‚¬μ΄νŠΈκ°€ μžˆλ‹€λŠ” 것을 μ•Œμ•˜λ‹€. (N ≀ M)

μž¬μ›μ΄λŠ” μ„œμͺ½μ˜ μ‚¬μ΄νŠΈμ™€ 동μͺ½μ˜ μ‚¬μ΄νŠΈλ₯Ό λ‹€λ¦¬λ‘œ μ—°κ²°ν•˜λ €κ³  ν•œλ‹€. (μ΄λ•Œ ν•œ μ‚¬μ΄νŠΈμ—λŠ” μ΅œλŒ€ ν•œ 개의 λ‹€λ¦¬λ§Œ 연결될 수 μžˆλ‹€.)

μž¬μ›μ΄λŠ” 닀리λ₯Ό μ΅œλŒ€ν•œ 많이 μ§€μœΌλ €κ³  ν•˜κΈ° λ•Œλ¬Έμ— μ„œμͺ½μ˜ μ‚¬μ΄νŠΈ 개수만큼 (N개) 닀리λ₯Ό μ§€μœΌλ €κ³  ν•œλ‹€. λ‹€λ¦¬λΌλ¦¬λŠ” μ„œλ‘œ 겹쳐질 수 μ—†λ‹€κ³  ν•  λ•Œ

닀리λ₯Ό 지을 수 μžˆλŠ” 경우의 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ.

example

πŸ” 접근법

Q.1010 닀리 놓기 문제 ν’€μ΄μž…λ‹ˆλ‹€.

λ¬Έμ œμ—μ„œ 주어진 쑰건 쀑 κ°€μž₯ μ€‘μš”ν•œ 점은

닀리가 μ—‡κ°ˆλ¦¬κ²Œ κ³‚μΉ˜μ§€μ•Šμ•„μ•Ό ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€!

닀리가 μ—‡κ°ˆλ¦¬μ§€ μ•ˆκ²Œ 닀리λ₯Ό λ§Œλ“œλ €λ©΄ 경우의 μˆ˜λŠ” n<=m μΌλ•Œλ§Œ μ„±λ¦½ν•˜κ³ 

λͺ¨λ‘ 1:1 λŒ€μ‘μ΄ λ˜μ–΄μ•„ν–‘λ‹ˆλ‹€.

결과적으둜 μˆœμ„œμ— 상관없이 m개 쀑 n개λ₯Ό λ½‘λŠ” 경우의 수 (μ‘°ν•©)이 닡이 λ©λ‹ˆλ‹€.

mCn = m-1 C r-1 + m C r-1 κ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ‘°ν•© 전체 경우의수  = μ–΄λ–€ ν•œ μ›μ†Œλ₯Ό 이미 μ„ νƒν•œ 경우 + ν•˜λ‚˜μ˜ μ›μ†Œλ₯Ό μ„ νƒν•˜μ§€ μ•Šμ„ 경우의 수

이λ₯Ό μ΄μš©ν•΄ μž¬κ·€μ μœΌλ‘œ

public static int combination(int n, int r) {
        if (n == r || r == 0)
            return 1;
        else if(dp[n][r] > 0)
            return dp[n][r];
        else
            return dp[n][r] = combination(n - 1, r - 1) + combination(n - 1, r);
}

combination ν•¨μˆ˜λ₯Ό 톡해 닡을 ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

단 μ‹œκ°„ μ†Œμš”λ₯Ό 쀄이기 μœ„ν•΄

λ™μ ν”„λ‘œκ·Έλž˜λ°μ˜ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ 톡해 ν’€μ΄ν•©λ‹ˆλ‹€.

πŸ’» μ½”λ“œ

package problem.dynamic;

import java.io.*;

public class Main_1010 {

    static int n,m;
    static int T;
    static StringBuilder sb;
    static int dp[][];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        T = Integer.parseInt(br.readLine());
        sb = new StringBuilder();
        for(int i=0; i<T; i++){
            String[] temp = br.readLine().split(" ");
            n = Integer.parseInt(temp[0]);
            m = Integer.parseInt(temp[1]);
            dp = new int[m+1][n+1];
            sb.append(combination(m,n)+"\n");
        }
        bw.write(sb.toString());
        br.close();
        bw.flush();
        bw.close();
    }

    public static int combination(int n, int r) {
        if (n == r || r == 0)
            return 1;
        else if(dp[n][r] > 0)
            return dp[n][r];
        else
            return dp[n][r] = combination(n - 1, r - 1) + combination(n - 1, r);
    }
}
Written on February 9, 2021