문제
0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오.
덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우). 또한 한 개의 수를 여러 번 쓸 수도 있다.
입력
첫째 줄에 두 정수 N(1 ≤ N ≤ 200), K(1 ≤ K ≤ 200)가 주어진다.
출력
첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.
예제 입력 1
20 2
예제 출력 1
21
풀이 .
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int[][] dp = new int[n + 1][k + 1];
dp[0][0] = 1;
for(int i = 0; i <= n; i++) {
for (int j = 1; j <= k; j++) {
for (int m = 0; m <= i; m++) {
dp[i][j] += dp[i - m][j - 1];
dp[i][j] %= 1000000000;
}
}
}
System.out.println(dp[n][k]);
}
}
점화식을 도출하는 과정이 codeung.tistory.com/124 와 비슷한 느낌이다.
결국 이것도 못 풀고 정답코드를 확인했다..
dp[n][k] = 숫자 n을 숫자 k개의 조합으로 만들 수 있는 경우의 수 (k개의 숫자들을 더한 결과가 n이 되는 경우의 수)
n = ? + ? + ? + ... + m 에서 점화식을 유도할 수 있다.
dp[n][k] = dp[n - m][k - 1] (0 <= m <= n 의 모든 m에 대한 값을 더한 것이 dp[n][k]가 된다.)
n은 1~200인데 i 반복은 0부터 시작하는 이유?
[0][1]~[0][k] 를 먼저 구해놔야 다음 반복의 점화식에서 사용할 수 있다.
[0][1]~[0][k] 는 어차피 전부 1이니까 (0만 k개 더하는 경우) 좀 더 명확하게 알아보기 위해 초기화용 반복을 따로 돌리고 본 반복은 i = 1 부터 시작하는 것도 방법이다.
O(k*n^2) 의 시간으로 정답을 구할 수 있다.
너무.. 어렵다.....
'알고리즘 문제 > 백준 온라인 저지' 카테고리의 다른 글
[BOJ] 11052 - 카드 구매하기 JAVA (0) | 2021.01.13 |
---|---|
[BOJ] 2011 - 암호코드 JAVA (0) | 2021.01.13 |
[BOJ] 9461 - 파도반 수열 JAVA (0) | 2021.01.13 |
[BOJ] 2133 - 타일 채우기 JAVA (0) | 2021.01.13 |
[BOJ] 1699 - 제곱수의 합 JAVA (0) | 2021.01.12 |