코딩 테스트

[백준] 2225번 - 합분해

2022. 9. 27. 09:20
반응형

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

 

2225번: 합분해

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

 

합분해 문제이다.

 

해당 문제를 이해하기 위해서 간단한 예시를 들어보자.

 

만약 N = 4, K= 2 인 경우를 생각해보자.

 

그럼 숫자 4를 0~4 의 숫자로 두개를 합해서 만들어야 하는 경우의 수를 구하면 된다.

 

그럼 아래와 같은 순서쌍이 나오게 된다.

 

(0,4), (4,0), (3,1), (1,3), (2,2)

 

위와 같이 5개의 순서쌍이 나와서 5개가 답이된다.

 

그럼 이제 일반화 가정을 거쳐보자.

 

(0,4), (4,0), (3,1), (1,3), (2,2)

 

위와 같이 순서쌍을 뽑는다고 가정했을 경우에 

 

4 = x + r

 

이라고 볼 수 있다.

 

여기서 x 와 r 의 관계는 x 가 정해지면 r은 자연스럽게 정해진다고 생각하면 편하다.

 

그래서 위의 순서쌍에 빨간표시를 해둔것을 본다면

 

0을 선택하면 자연스럽게 4가 정해지고, 4를 택하면 자연스럽게 0이 정해지는 것이다.

 

즉 점화식을 사용하여 일반화 시켜보면 아래와 같다.

 

dp[K][N] = dp[K-1][0] + dp[K-1][1] + ... + dp[K-1][N] 

 

위의 점화식을 해석해보면 0~N 까지의 숫자 K 개로 N 을 만들때,

 

dp[K-1][0] 은 0을 선택하는 경우고

 

dp[K-1][1] 은 1을 선택하는 경우라고 생각하면 된다.

 

그리고 논리적으로 dp[0][i] (i ∈ (0,1,2,...,N)) 은 무조건 0이 된다.

 

왜냐하면 0개로 N 을 만들수 있는 방법은 0이기 때문이다.

 

dp[1][i] (i ∈ (0,1,2,...,N)) 는 무조건 1이 된다.

 

0 ~ N 숫자중에 하나를 뽑아서 N 을 만드는 방법은 한가지 뿐이기 때문이다.

 

dp[i][0] (i ∈ (0,1,2,...,K)) 또한 1이다. 0 을 만드는 방법은 0 하나를 택하는 방법 하나뿐이기 때문이다.

 

N = 4, K = 2 일때의 경우를 생각해보자. (dp[K][N] 기준이다.)

 

dp[2][1] = dp[1][0] + dp[1][1]

 

 

dp[2][4] = dp[1][0] + dp[1][1] + dp[1][2] + dp[1][3] + dp[1][4]

 

 

 

 

1. C++ 를 이용한 풀이

 

#include <iostream>

using namespace std;

int N,K;
long dp[201][201];
long DIV = 1000000000;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    cin >> N >> K;

    dp[0][0] = 1;

    for (int i = 1; i <= K; i++) {
        for (int j = 0; j <= N; j++) {
            for (int k = 0; k <= j; k++) dp[i][j] += dp[i-1][k]; 
            
            dp[i][j] %= DIV;
        }
    }

    cout << dp[K][N];

    return 0;
}

 

 

 

2. JAVA 를 이용한 풀이

 

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

public class Main {
	
	static int N,K;
	static long DIV = 1000000000;
	static long[][] mat;
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer stk = new StringTokenizer(br.readLine());
		
		N = Integer.parseInt(stk.nextToken());
		K = Integer.parseInt(stk.nextToken());
		
		mat = new long[K+1][N+1];
		
		mat[0][0] = 1;
		
		for (int i = 1; i <= K; i++) {
			for (int j = 0; j <= N; j++) {
				for (int k = 0; k <= j; k++) mat[i][j] += mat[i-1][k]; 
				
				mat[i][j] %= DIV;
 			}
		}
		
		
		bw.write(mat[K][N] + "");
		bw.close();
		br.close();
		
	}
}

 

 

그런데 위와 같은 알고리즘 말고 다른 알고리즘도 생각해 볼 수 있다.

 

dp[K][N] = dp[K-1][0] + dp[K-1][1] + ... + dp[K-1][N-1] + dp[K-1][N] 

 

인데 dp[K-1][0] + dp[K-1][1] + ... + dp[K-1][N-1] = dp[K][N-1] 이라고 볼 수 있다.

 

즉, dp[K][N] = dp[K][N-1] + dp[K-1][N] 로 일반화 시킬 수 있다.

 

 

위의 알고리즘을 만들어보면 아래와 같다.

 

#include <iostream>

using namespace std;

int N,K;
long dp[201][201];
long DIV = 1000000000;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    cin >> N >> K;

    for (int i = 1; i <= K; i++) dp[i][0] = 1;
    for (int i = 0; i <= N; i++) dp[1][i] = 1;
    
    for (int i = 1; i <= K; i++) {
        for (int j = 1; j <= N; j++) {
            long sum = dp[i][j-1] + dp[i-1][j];
            dp[i][j] = sum % DIV;
        }
    }

    cout << dp[K][N];

    return 0;
}
반응형

'코딩 테스트' 카테고리의 다른 글

[백준] 1915번 - 가장 큰 정사각형  (4) 2023.07.09
[백준] 2240번 - 자두나무  (0) 2022.10.01
백준 1937번 - 욕심쟁이 판다  (1) 2022.08.30
백준 18223번 - 민준이와 마산 그리고 건우  (0) 2022.05.24
백준 1854번 - K번째 최단경로 찾기  (0) 2022.05.11
'코딩 테스트' 카테고리의 다른 글
  • [백준] 1915번 - 가장 큰 정사각형
  • [백준] 2240번 - 자두나무
  • 백준 1937번 - 욕심쟁이 판다
  • 백준 18223번 - 민준이와 마산 그리고 건우
ssh9308
ssh9308
신승환의 기술 블로그
신승환의 기술 블로그신승환의 기술 블로그
반응형
ssh9308
신승환의 기술 블로그
ssh9308
전체
오늘
어제
  • 분류 전체보기 (203)
    • SQL Basic (11)
    • SQL Tuning (11)
    • DB ARCHITECTURE (21)
    • 컴퓨터 구조 (6)
    • 코딩 테스트 (25)
    • 알고리즘 (5)
    • JAVA (4)
    • 개발 & 구현 (6)
    • C,C++ (5)
    • 면접대비 자료 (1)
    • JS (3)
    • MongoDB (6)
    • Redis (7)
    • 네트워크 (38)
    • bash shell (0)
    • Kafka (2)
    • Elasticsearch (11)
    • Spring (1)
    • SQL SERVER ARCHITECTURE (0)
    • Python (1)
    • RUST (12)
    • 보안 (3)
    • 운영체제 (19)
    • 결혼관련 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 가성비
  • 웨딩링
  • 커플링
  • 공방301
  • 고급
  • 종로
  • 다이아
  • 웨딩밴드
  • 예물

최근 댓글

최근 글

hELLO · Designed By 정상우.
ssh9308
[백준] 2225번 - 합분해
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.