프로그래밍 공부/백준 (C++)
[C++ / 백준 2225번] 합분해
Rocketbabydolls
2024. 11. 23. 21:04
음... 초반 경우의 수를 찾아 규칙을 통해 점화식을 세웠는데, 점화식은 세워서 정답을 맞췄지만 왜 그 점화식이 도출되는지는 모르는 사태가 발생했다.
따라서 GPT 에게 도움을 요청했다.
경우의 수는 두 가지로 나눌 수 있었는데,
- dp[i-1][j]: 숫자 i-1을 j개의 숫자로 표현한 후, 마지막 숫자에 1을 더하는 경우.
- dp[i][j-1]: 숫자 i를 j-1개의 숫자 합으로 표현한 후, 마지막 숫자에 1을 더하는 경우.
이렇다고 한다.
i = 3, j = 2 일때를 예시로 들자.
dp[2][2] = (02 20 11) = 3
dp[3][1] = (3) = 1
dp[3][2] = (03 30 12 21 ) = 4
인데
dp[2][2] 에 i를 1 늘리는 경우
1 + 2
2 + 1
0 + 3
이고.
dp[3][1] 에 j 를 1 늘이는 경우
뒤에 0 을 붙여준다.
3 + 0 (다른 순서도 인정하므로 이 경우도 +1 이 된다.)
따라서 dp[3][2] = 4 가 된다.
같은 논리로 뒤 점화식도 동일하게 계산된다.
2차원 배열일 시에 i, j 의 각 경우의 수를 dp로 나눠준다는 것을 명심해야겠다.
#include <iostream>
#include <vector>
using namespace std;
#define MOD 1000000000
int main() {
int N, K;
cin >> N >> K;
// dp[i][j]: 숫자 i를 j개의 숫자의 합으로 표현하는 경우의 수
vector<vector<int>> dp(N + 1, vector<int>(K + 1, 0));
// 초기화
for (int j = 1; j <= K; j++) {
dp[0][j] = 1; // 숫자 0을 j개의 숫자의 합으로 표현하는 방법은 1가지
}
// 점화식 계산
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= K; j++) {
dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % MOD;
}
}
// 결과 출력
cout << dp[N][K] << endl;
return 0;
}