n가지 종류의 동전이 있다. 각각의 동전이 나타내는 가치는 다르다. 이 동전을 적당히 사용해서, 그 가치의 합이 k원이 되도록 하고 싶다. 그 경우의 수를 구하시오. 각각의 동전은 몇 개라도 사용할 수 있다.
사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.
첫째 줄에 n,k가 주어진다. (1<=n<=100, 1<=k<=10,000) 다음 n개의 줄에는 각각의 동전의 가치가 주어진다. 동전의 가치는 100,000보다 작거나 같은 자연수이다.
첫째 줄에 경우의 수를 출력한다. 경우의 수는 2^31보다 작다.
완전탐색으로 풀 경우,
시간초과
가 발생한다.(시간제한이0.5초
이기 때문이다.)
때문에 DP를 사용할 필요가 있다. DP를 어떻게 활용할 수 있을까?
구해야 하는 값은 합이 k가 되는 경우의 수이다. 그렇다면 0부터 k까지의 수를 n(0 <= n <= k)이라고 하자. 주어진 수(동전의 가치)를 더해서 각각의 n을 만들 수 있는 경우의 수를 구해나가면 최종적으로 k를 만들 수 있는 경우의 수를 구할 수 있다.
예를 들어, nums = [1,2,5], k = 10 의 경우
2을 만들 수 있는 경우의 수는 1에서 1를 더하거나(이 결과는 현재 dp[2]와 동일하다.) 0에서 2를 더하면 된다(이 결과는 0을 만드는 경우의 수와 동일함을 알 수 있다. 0을 만드는 조합에서 마지막에 2만 추가된 것이기 때문이다.).
즉, dp[2] = dp[2] + dp[0]이 된다.
n, k = map(int, input().split())
nums = [ int(input()) for _ in range(n) ]
dp = [0 for _ in range(k+1)]
dp[0] = 1
for num in nums :
for i in range(1, k+1) :
if i - num >= 0 :
dp[i] += dp[i-num]
print(dp[k])
역시 아직 DP 문제
를 푸는데 시간이 많이 소요되고 있다. DP 문제
와 관련해서는 많이 풀어보고, 복습하자.