알고리즘

파이썬 / BOJ / 11047 (동전 0)

snowfield 2020. 4. 17. 16:03

문제

준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다.

동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 최솟값을 구하는 프로그램을 작성하시오

입력

첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000)

둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)

출력

첫째 줄에 K원을 만드는데 필요한 동전 개수의 최솟값을 출력한다.

풀이

나는 이 문제에서 가치가 가장 큰 거부터 할당하는 식으로 하여 문제를 풀었다(탐욕법 이용 -> 현재 상황에서 최적의 선택을 하는 것) 

import sys

N, K = map(int,sys.stdin.readline().split(" "))
coin_list = [0]*N
counting_coin = 0
redundancy_coin = K

for i in range(N-1,-1,-1):
    temp_coin = int(sys.stdin.readline())
    coin_list[i] = temp_coin

for i in range(N):
    if coin_list[i] <= redundancy_coin :
        counting_coin += redundancy_coin//coin_list[i]
        redundancy_coin = K % coin_list[i]
        
print(counting_coin)

아쉬운 점은 먼저 coin_list를 0으로 해놓고 for문을 돌려서 채웠는데, 그렇지 않고 먼저 for문을 이용해서 들어오는 순서대로 넣은다음,

배열의 리스트를 [-인덱스]로 접근하는 방식으로 하여 뒤부터 접근하는 식으로 하는 방법도 코드를 깔끔하게 짤 수 있을 거 같다.

그리고 나는 redundancy_coin이라는 변수를 만들어서 계속해서 나머지 돈을 갱신하는 방법으로 했는데 그렇지 않고, 그냥 K변수에서 나머지만큼 계속 빼도록 하는게 훨씬 더 코드가 간결해질 거 같다.

 

개선 코드

앞선 코드보다 훨씬 짧아진 걸 볼 수 있다.

import sys

N, K = map(int,sys.stdin.readline().split(" "))
coin_list = [int(sys.stdin.readline()) for _ in range(N)]
counting_coin = 0

for i in range(1,N+1):
    coin = coin_list[-i]
    
    if coin <= K :
        counting_coin +=  K//coin
        K = K%coin
        
print(counting_coin)