[백준/골드4] 2293번 동전 1 | DP | 파이썬

문제

https://www.acmicpc.net/problem/2293

n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 각각의 동전은 몇 개라도 사용할 수 있다.

사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.

 

입력

첫째 줄에 n, k가 주어진다. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다.

 

출력

첫째 줄에 경우의 수를 출력한다. 경우의 수는 231보다 작다.

 

예제

 

다른 사람의 풀이

n, k = map(int, input().split())
coins = [int(input()) for _ in range(n)]

dp = [0] * (k + 1)
dp[0] = 1

for c in coins:
    for i in range(c, k + 1):
        dp[i] += dp[i - c]

print(dp[k])

`dp[x]`에 x원을 만드는 경우의 수를 저장한다.

`dp[0] = 1`으로 초기화하고, (0원을 만드는 방법은 아무 동전도 사용하지 않는 방법 한 가지)

각 동전의 값부터 `k`까지 순회하면서 횟수를 누적해나간다.

 

`dp[i] += dp[i - c]` 점화식은 다음과 같은 의미를 가진다.

`i`원을 만드는 경우의 수를 구하려면,

`i-c`원을 만드는 경우의 수에 동전 c를 하나 더 사용하는 방법을 추가한다.

 

예를 들어 동전이 `{2}`만 있다고 하고, `i = 6`원을 만든다고 해보자.

  • `dp[6] += dp[6 - 2]`
  • 즉, "6원을 만드는 방법"은 "4원을 만드는 방법에 2원을 하나 더 사용하는 것"이 된다.

 

회고

처음엔 DP에 경우의 수에 따른 값을 모두 저장하는 방법을 생각했었는데, 간단하게 횟수 자체를 저장하면 되는 거였다. 이런 문제 유형 자주 나오는 거 같아서 많이 익숙해져야겠다.

 

참고