💯Problem Solving
[BOJ] 2225 합분해
date
Aug 5, 2023
slug
boj-2225
author
status
Public
tags
Python
BOJ
summary
백준 0000번 문제풀이입니다.
type
Post
thumbnail
category
💯Problem Solving
updatedAt
Aug 20, 2023 06:31 PM
문제 링크
문제
0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오.
덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우). 또한 한 개의 수를 여러 번 쓸 수도 있다.
문제풀이
문제 자체는 DP 테이블을 그릴 수 있다면 금방 풀리지만, 납득이 잘 안되는 문제
ㅤ | N=0 | N=1 | N=2 | N=3 | N=4 | N=5 |
K=1 | 1 | 1 | 1 | 1 | 1 | 1 |
K=2 | 1 | 2 | 3 | 4 | 5 | 6 |
K=3 | 1 | 3 | 6 | 10 | 15 | 21 |
dp[K][N] = dp[K-1][N] + dp[K][N-1]
dp[K][N-1] = dp[K-1][N-1] + dp[K][N-2]로 바꿀수 있고 계속 이런식으로 바꾸면
dp[K][N-1] = sum(dp[K-1][0] ~ dp[K-1][N-1]) 인것을 점화식을 통해서 알아 낼 수 있다.
식은 이렇게 유추할 수 있다지만 어째서? 어째서 이렇게 되는가를 알아내지 못하여 추가적으로 검색을 통하여 나름 납득이되는 해답을 찾을 수 있었다.
이 블로그에서 잘 설명해줬듯이

이 그림에서
예를들어 N=6, K=4라면
a+b+c+d = 6 이라는 조건이
a+b+c = 6-d라는 조건으로 바꿀 수 있고
이는
6-d를 k-1개를 사용하여 만족시키는 경우와 같고
d는 0~6이 될수 있으므로
dp[k-1][0] + dp[k-1][1] + dp[k-1][2] + dp[k-1][3] + dp[k-1][4] + dp[k-1][5] + dp[k-1][6] 이 되고
이는 위에서 구했던 점화식과 완전히 같은 형태이다.
파이썬 문제풀이 코드
N, K = map(int, input().split()) dp = [[1] * (N+1) for _ in range(K+1)] # dp[k][n] = dp[k][n-1] + dp[k-1][n] for i in range(2, K+1): for j in range(1, N+1): dp[i][j] = (dp[i][j-1] + dp[i-1][j]) % int(1e9) print(dp[K][N])
시간복잡도
- O(KN)
입력
첫째 줄에 두 정수 N(1 ≤ N ≤ 200), K(1 ≤ K ≤ 200)가 주어진다.
출력
첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.
6 4
84
알고리즘 분류
- 구현
- 문자열