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

 

1010번: 다리 놓기

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

www.acmicpc.net

코드설명

DP 문제입니다.

 

M개의 사이트에서 N개의 사이트를 뽑는 조합을 이용합니다. 

순서는 중요하지 않으므로 다 뽑고 난 이후에 저절로 다리가 겹치지 않도록 바꿔주면 되므로 

조합을 구한다면, 다리가 겹치치 않게 설정할 수 있습니다.

 

파스칼 삼각형에서 조합의 규칙성을 이용합니다.

nCr = n-1Cr-1 + n-1Cr

nCr( n==r ) = 0,
nC0 = 0

 

 

코드

Bottom-Up, 배열을 활용한 코드입니다.

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

public class Main {
	public static int T;
	public static int answer = 0;
	public static int[][] dp;
    public static void main(String[] args) throws IOException{
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	StringTokenizer st = new StringTokenizer(br.readLine());
    	
    	T = Integer.parseInt(st.nextToken());
    	dp = new int[31][31];
    	
    	//파스칼 삼각형의 nC0 , nCn 을 처리합니다. 
    	for(int i=0;i<30;i++) {
    		dp[i][i] = 1;
    		dp[i][0] = 1;
    	}
    	
    	//nCr = n-1Cr-1 + n-1Cr 을 구현합니다.
    	for(int i=2; i<30;i++) {
    		for(int j=1;j<30;j++) {
    			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
    		}
    	}
    	
    	for(int i=0;i<T;i++) {
    		st = new StringTokenizer(br.readLine());
    		int N = Integer.parseInt(st.nextToken());
    		int M = Integer.parseInt(st.nextToken());
    		
    		System.out.println(dp[M][N]);
    	}
    }
   
}

 

Top-Down, 재귀를 활용한 코드입니다.

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

public class Main {
	public static int T;
	public static int answer = 0;
	public static int[][] dp;
    public static void main(String[] args) throws IOException{
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	StringTokenizer st = new StringTokenizer(br.readLine());
    	
    	T = Integer.parseInt(st.nextToken());
    	dp = new int[31][31];
    	for(int i=0;i<T;i++) {
    		st = new StringTokenizer(br.readLine());
    		int N = Integer.parseInt(st.nextToken());
    		int M = Integer.parseInt(st.nextToken());
    		
    		System.out.println(combination(M, N));
    	}
    		
    	
    	
    }
    
    public static int combination(int n, int r) {
    	
    	//이미 계산된 값일 경우
    	if(dp[n][r] > 0) {
    		return dp[n][r];
    	}
    	
    	// n과 r 일경우 뽑는 방법은 무조건 1개입니다.
    	// r == 0일경우 하나도 뽑지 않기에 1개입니다.
    	// 파스칼 삼각형에서 맨끝과 맨끝을 의미합니다.
    	if(n == r || r == 0) {
    		return dp[n][r] = 1;
    	}
    	
    	//
    	else {
    		return dp[n][r] = combination(n - 1, r - 1) + combination( n - 1, r);
    	}
    	
    }
    
}

+ Recent posts