티스토리 뷰

PS/백준

[백준] 2294 동전2

HUN 2021. 2. 7. 14:53


n개의 동전이 주어지고 최소한의 동전을 합하여 k원을 만드는 문제이다.

 

그리디, 동적 프로그래밍 두 가지 접근 방법이 가능하나, 나는 그리디 알고리즘 밖에 떠올리지 못하였다.

 

그리디

우선순위 큐를 가지고 그리디 알고리즘을 사용하면 메모리초과가 발생할 수 있다. 우선순위 큐에 들어갈 수를 직접 작성해보면 중복된 수 가 상당히 많이 삽입되기 때문에 이미 만들어진 합을 제외하면 메모리 초과를 해결 할 수 있다.

 

동적  프로그래밍

사실 이 문제는 동적 프로그래밍으로 분류되는 문제이기 때문에 그리디 풀이법이 출제자가 의도한 것은 아닐 것이다. 

 

동적 프로그래밍으로 해결하기 위해서는 점화식을 만들 수 있어야한다.

 

어떤 n 원을 만들기 위해서는 임의의 m원에서 주어진 동전 중 하나를 더해야 한다. n원을 만들기 위해 사용된 최소한의 동전 개수를 담고있는 배열을 D라고 하면 점화식은 아래와 같다.

 

n = m + coins[i]

m = n - coins[i]

 

D[n] = min(D[n], D[n - coins[i]) + 1)

소스 코드

from sys import stdin
import heapq

readline = stdin.readline


def main():
    n, k = map(int, readline().split())
    coins = [int(readline()) for _ in range(n)]    
    print(greedy_solve(k, coins))
    print(dp_solve(n, k, coins))


def dp_solve(n, k, coins):
    d = [10001] * (k+1)
    d[0] = 0
    for i in range(n):
        for j in range(coins[i], k+1):
            d[j] = min(d[j], d[j-coins[i]] + 1)

    if d[k] == 10001:
        return -1
    return d[k]

def greedy_solve(k, coins):
    pq = []
    heapq.heappush(pq, [0, k])
    visited = set()
    while pq:
        d, cur = heapq.heappop(pq)

        if cur == 0:
            return d

        for coin in coins:
            if cur - coin > 0 and cur - coin not in visited:
                heapq.heappush(pq, [d+1, cur-coin])
                visited.add(cur-coin)
            elif cur - coin == 0:
                return d + 1
    return -1

if __name__ == "__main__":
    main()
728x90

'PS > 백준' 카테고리의 다른 글

[백준] 1937 욕심쟁이 판다  (0) 2021.02.10
[백준] 10844 쉬운 계단 수  (0) 2021.02.09
[백준] 2156 포도주 시식  (0) 2021.02.07
[백준] 10835 카드게임  (0) 2021.02.06
[백준] 13460 구슬탈출2  (0) 2021.02.05
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함