Baekjoon
2225 - 합분해
kjy0349
2022. 4. 19. 18:04
문제
0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오.
덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우). 또한 한 개의 수를 여러 번 쓸 수도 있다.
해당 경우의 수를 1,000,000,000로 나눈 나머지를 출력하시오.
점화식을 구하기 위해 이전 항을 생각해보면, 정수 한 개를 빼야 하므로 d[K - 1]\[N - ?]와 같이 나타낼 수 있다. ?는 여러가지 경우가 있기 때문에 답을 구하기 전에는 알 수 없는 값으로, 이러한 수들을 반복문을 이용해 찾아주어야 한다.
따라서 d[K][N] = sum(d[K - 1]\[0 ~ N])과 같은 식을 가지고 구현을하면 된다.
위와 같이 식이 나온 이유는, K - 1번째 항의 값을 예측 할 수가 없기 때문이다. (ex : N이 5이고 K가 2라고하면 5는 0 + 5, 1 + 4, 2 + 3, 3 + 2, 4 + 1, 5 + 0 과 같은 경우들이 있다. 이 때 K - 1번째 항의 값은 계속해서 변하게 된다.)
점화식을 이용하기 위해 d[1][0 ~ N]값들을 모두 1로 초기화해 주었다.(한자릿수를 만들기 위해서는 무조건 수 한 개만 사용하기 때문.) 반복문이 3개인 이유는 K, N과 함께 Ln도 0부터 N까지 반복하며 개수를 세줘야 하기 때문이다. d[K - 1]\[0 ~ N] <- 0 ~ N 부분이 Ln으로 대체.
package backjoon;
import java.io.*;
public class Sum_of_Disassemble {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int K = Integer.parseInt(inputs[1]);
int[][] d = new int[K + 1][N + 1];
for (int i = 0;i <= N;i++) d[1][i] = 1; // d[1] 모든 항 1로 초기화
for (int i = 2;i <= K;i++){ // K
for (int j = 0;j <= N;j++) { // N
for (int x = 0;x <= j;x++){ // Ln
d[i][j] += d[i - 1][j - x];
d[i][j] %= 1000000000;
}
}
}d
System.out.println(d[K][N]);
}
}