본문 바로가기

알고리즘/파이썬

082 - 동전교환(DFS와 Dynamic/Knapsack 비교)

다음과 같이 여러 단위의 동전들이 주어져 있을때 거스름돈을 가장 적은 수의 동전으로 교환 해주려면 어떻게 주면 되는가? 각 단위의 동전은 무한정 쓸 수 있다.

 

 

입력설명
첫 번째 줄에는 동전의 종류개수 N(1<=N<=12)이 주어진다.

두 번째 줄에는 N개의 동전의 종 류가 주어지고,

그 다음줄에 거슬러 줄 금액 M(1<=M<=500)이 주어진다.
각 동전의 종류는 100원을 넘지 않는다.

 

출력설명
첫 번째 줄에 거슬러 줄 동전의 최소개수를 출력한다.

 

입력예제 1

3
1 2 5
15

 

출력예제 1

3

 

 

 

import time
import sys
name = 'in.txt'
#sys.stdin = open(name, 'rt')


def DFS(L, sum):
    global res

    if L > res:
        return
    elif sum > m:
        return
    elif sum == m:
        if L < res:
            res = L
    else:
        for i in range(n):
            DFS(L+1, sum+a[i])


if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))
    m = int(input())
    dy = [1000]*(m+1)
    dy[0] = 0
    print(f'{name}, n:{n}, a:{a}, m:{m}')
    # print(f'dy: {dy}')

    # =============== Dynamic, Knapsack ===============
    print('=============== Dynamic, Knapsack ===============')
    start = time.time()
    for i in range(n):
        for j in range(a[i], m+1):
            if dy[j] > dy[j-a[i]]+1:
                dy[j] = dy[j-a[i]]+1
        # print(f'i:{i},{j}, {a[i]} dy: {dy}')
    end = time.time()
    print(f'result:{dy[m]}, time:{(end-start)*1000:5.5}ms')
    # =============== Dynamic, Knapsack ===============

    # =============== Dynamic, DFS ===============
    print()
    print('=============== Dynamic, DFS ===============')
    start = time.time()
    res = float('inf')
    # a.sort(reverse=True)
    DFS(0, 0)
    end = time.time()
    print(f'result:{res}, time:{(end-start)*1000:5.5}ms')
    # =============== Dynamic, DFS ===============

 

 

Knapsack 방식이 DFS 방식에 비해서 빠른것을 알 수 있다.

 

in.txt, n:3, a:[1, 2, 5], m:15
=============== Dynamic, Knapsack ===============
result:3, time:0.016212ms

=============== Dynamic, DFS ===============
result:3, time:0.31281ms