post image post image post image post image post image post image post image post image

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

 

2225번: 합분해

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

www.acmicpc.net

 

DP로 풀 수 있는 문제다.

 

DP[N][K]라고 할 때,

 

1. 1 ~ K개의 수로 0을 만드는 경우의 수는 모두 1이다.

   -> DP[0][1 ~ K] = 1

 

2. K개의 숫자로 N을 만드는 경우의 수는 K-1개의 숫자로 0 ~ N을 만드는 경우의 수의 합과 같다.

예를 들면,

N=1,K=1 -> DP[1][1] = DP[1][0] + DP[0][0] = 1      (모든 경우> 1)

N=1,K=2 -> DP[1][2] = DP[1][1] + DP[0][1] = 2      (모든 경우> 0 + 1, 1 + 0)

.

.

.

N=2,K=1 -> DP[2][1] = DP[2][0] + DP[1][0] + DP[0][0] = 1  (모든 경우> 2)

N=2,K=2 -> DP[2][2] = DP[2][1] + DP[1][1] + DP[0][1] = 3  (모든 경우> 2 + 0, 1 + 1, 0 + 2)

 

따라서 점화식은 다음과 같다.

DP[n][k] = DP[n][k-1] + DP[n-1][k-1] + ... + DP[1][k-1] + DP[0][k-1]
           = ∑ DP[m][k-1]  (단, 0 <= m <= n)

코드로 구현하면 아래와 같다.

#include <iostream>

using namespace std;

//d[1][1] = d[0][0], d[1][2] = d[1][1] + d[0][1], ...
//d[2][1] = d[0][0], d[2][2] = d[2][1] + d[1][1] + d[0][1], ...


int N, K;
int d[201][201];
const int MOD = 1e9;

void dp() {
	//초기값
	for (int i = 0; i < K; i++) {
		d[0][i] = 1;
	}

	//i는 만들고자 하는 수
    //j는 사용한 숫자의 개수
    //k는 i ~ 0까지의 수
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= K; j++) {
			for (int k = i; k >= 0; k--) {
            	//두 값 모두 1e9보다 작으므로 모듈러 연산을 취하지 않고 
                //더한 후 모듈러 연산을 취해도 괜찮다.
				d[i][j] += d[k][j - 1];
				d[i][j] %= MOD;
			}
		}
	}

	cout << d[N][K];
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> N >> K;
	dp();
	return 0;
}
메모리: 2180 kb 시간: 12 ms

 

'컴퓨터 사이언스 > 1고리즘' 카테고리의 다른 글

백준 2631 : 줄세우기  (0) 2021.07.31
백준 3020 : 개똥벌레  (0) 2021.07.31
백준 1504 : 특정한 최단 경로  (0) 2021.07.30
백준 5214 : 환승  (0) 2021.07.28
백준 2606 : 바이러스  (0) 2021.07.28

+ Recent posts