반응형
문제설명
명보네 동네 가게의 현금 출납기에는 k가지 동전이 각각 $n_1, n_2, ..., n_k$개 씩 들어있다. 가게 주인은 명보에게 T원의 지폐를 동전으로 바꾸어 주려고 한다. 이 때, 동전 교환 방법은 여러가지가 있을 수 있다. 예를 들어, 10원, 5원, 1원 동전이 각각 2개, 3개, 5개씩 있을 때, 20원 짜리 지폐를 다음과 같은 4가지 방법으로 교환할 수 있다.
- 20 = 10원 x 2개
- 20 = 10원 x 1개 + 5원 x 2개
- 20 = 10원 x 1개 + 5원 x 1개 + 1원 x 5개
- 20 = 5원 x 3개 + 1원 x 5개
입력으로 지폐의 금액 T, 동전의 가지수 k, 각 동전 하나의 금액 $p_i$와 개수 $n_i$가 주어질때 지폐를 동전으로 교환하는 방법의 가지 수를 계산해라. 방법의 수는 $2^{31}$를 초과하지 않는 것으로 가정한다.
입력조건
- 첫줄에는 지폐의 금액 T(0 <= T <= 10,000), 둘째 줄에는 동전의 가지수 k(0 <= k <=10)이 주어진다.
- 셋째줄부터 마지막 줄까지는 각 줄에 동전의 금액 $p_i$(0 < $p_i$ <= T)와 $n_i$(0 <= $n_i$ <= 10)이 주어진다. $p_i$와 $n_i$사이에는 빈 칸이 하나씩 있다.
출력조건
- 첫 줄에 동전 교환 방법의 가지 수를 출력한다.(교환할 수 없는 경우는 존재하지 않는다.)
사고과정
- 처음에 상태트리를 만들때, 갈래를 각 동전 사용하는 경우에 따라 가지를 뻗어나가도록 했다. 이렇게 DFS를 구현했지만, 중복되는 경우를 제거하지 못했다.. 집합자료구조로 받았지만 시간초과가 발생.. 중복되는 경우를 탐색하는 데 시간이 초과된다..
- 강의를 보니, 상태트리 가지를 뻗어나갈 때, 해당 동전을 몇개 사용하는지에 따라 나누었다..아차 싶었다..
- 상태트리의 레벨을 주어진 동전의 인덱스로 설정하고, 해당 인덱스의 동전을 주어진 해당 동전의 개수 즉, 0개부터 $n_i$개까지의 for loop를 DFS 함수 안에 서 돈다.. 그리고 누적합이 목표 금액 T보다 커지게 되면 바로 탐색을 중단하는 cut-edge도 포함시켜야 시간초과가 발생하지 않는다.
- 아이디어만 듣고 소스코드로 구현하는 데는 어렵지 않았다.. 흐..상태트리를 만드는 아이디어를 생각해내기 쉽지 않다..
풀이(스스로 못 푼 풀이)
- 나의 풀이
T = int(input())
k = int(input())
p, n = [], []
for _ in range(k):
price, cnt = map(int, input().split())
p.append(price)
n.append(cnt)
answer = 0
def dfs(L, sum_val):
global answer
if sum_val == T:
answer += 1
return
elif L == k:
return
else:
for i in range(0, n[L]+1):
# cut-edge
if sum_val + (i * p[L]) <= T:
dfs(L+1, sum_val + (i * p[L]))
dfs(L=0, sum_val=0) # 동전의 idx, 누적합
print(answer)
- 강의 풀이
T = int(input())
k = int(input())
cv, cn = [], []
for _ in range(k):
a, b = map(int, input().split())
cv.append(a)
cn.append(b)
cnt = 0
def DFS(L, sum):
global cnt
if sum > T:
return
if L == k:
if sum == T:
cnt += 1
else:
for i in range(cn[L]+1):
DFS(L+1, sum + (cv[L] * i))
DFS(L=0, sum=0)
print(cnt)
반응형
'알고리즘 삽질장' 카테고리의 다른 글
[인프런] 알파코드 (0) | 2021.11.26 |
---|---|
[인프런] 동전 분배하기 (0) | 2021.11.26 |
[인프런] 양팔저울 (0) | 2021.11.25 |
[인프런] 퇴사 (0) | 2021.11.25 |
[인프런] 최대점수 구하기 (0) | 2021.11.25 |