알고리즘 :: 백준 :: DP :: 2225 :: 합분해

Embedded June·2020년 7월 26일
0

알고리즘::백준

목록 보기
23/109

문제

0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오. 덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우). 또한 한 개의 수를 여러 번 쓸 수도 있다.

문제접근

  1. 문제에 주어진 변수와 범위를 생각해보자
    1. K : 정수의 개수, 1KK(input)1 \leq K \leq K(input)
    2. N : 구하고자 하는 수 0NN(input)0 \leq N \leq N(input)
    3. L : 마지막에 오는 정수 0LN(input)0 \leq L \leq N(input)
  2. 따라서 이 문제는 3중 for문을 사용해야하는 문제다. 상한값을 계산하면, 200×200×200=8,000,000200 \times 200 \times 200 = 8,000,000 이므로 2초내로 문제를 풀 수 있다.
  3. 점화식 D[K][N]=D[K1][NL]D[K][N] = \sum D[K-1][N-L] 이다.
    즉, K개를 사용해서 N을 만드는 과정은 K-1개를 사용해서 N-L을 만드는 과정들의 합이다.

코드

#include <iostream>
using namespace std;

constexpr int MOD = 1000000000;
int N, K;
int dp[201][201] = {1,};    // 0은 그 자체로 경우의 수 1이므로

int solve() {
    for (int i = 1; i <= K; ++i)            // 개수: 1개부터 K개 까지
        for (int j = 0; j <= N; ++j)        // 숫자: 0부터 N까지 정수
            for (int l = 0; l <= j; ++l){   // 마지막 숫자: 0부터 j까지
                dp[i][j] += dp[i - 1][j - l];	// i개 숫자를 써서 j를 만드는 것은
                dp[i][j] %= MOD;				// i-1개 숫자를 써서 j-1 만드는 경우들의 합
            }
    return dp[K][N];
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> N >> K;
    cout << solve() << '\n';
}

결과

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글