링크 : https://school.programmers.co.kr/learn/courses/30/lessons/172927
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
코드
def solution(picks, minerals):
graph =[[1,1,1],
[5,1,1],
[25,5,1]]
def mineralNum(s):
if s == "diamond":
return 0
if s == "iron":
return 1
if s == "stone":
return 2
def DFS(cnt,prePick,total):
nonlocal answer,picks
if cnt >= len(minerals):
answer = min(answer,total)
return
mNum = mineralNum(minerals[cnt])
if (cnt+1) % 5 == 0:
if picks.count(0) == 3:
answer = min(answer,total+graph[prePick][mNum])
return
for pick in range(len(picks)):
if picks[pick] > 0:
picks[pick] -= 1
DFS(cnt+1, pick, total+graph[prePick][mNum])
picks[pick] += 1
return
else:
DFS(cnt+1, prePick, total+graph[prePick][mNum])
answer = 1e9
for pick in range(len(picks)):
if picks[pick] > 0:
picks[pick] -= 1
DFS(0,pick,0)
picks[pick] += 1
return answer
풀이
문제내용이 마인크래프트에서 영감을 받은 문제인 것 같아서 재밌었던 문제이다.
한 곡괭이당 무조건 5개씩 캘 수 있으니 5개를 캘 때마다 곡괭이를 바꿔주어야 한다.
처음에는 이 곡괭이를 바꿔줄 때 효율성을 계산해서 다음 5개를 가장 적은 시간에 해결할 수 있는 곡괭이를 선택할까 했다.
하지만 이 효율성을 계산하는 과정이 너무 복잡하고 따져야 할 조건이 많았다. 그래서 이 문제는 무조건 완전탐색이라고 생각했다.
5번째 광물, 즉 곡괭이를 바꿔줘야 할 타이밍이 올 때마다 DFS로 가지를 뻗어나간다.
각각의 가지들은 하나의 곡괭이를 선택하여 3방향씩 뻗어나가므로 시간복잡도는 3^10이 최대가 되어서 시간초과가 나지는 않을 것이라 생각했다.
모든 광물을 캐거나 곡괭이가 모두 사용되면 정답을 갱신하고 그렇지 않다면 계속해서 가지를 뻗어나간다.
가지를 뻗어나갈 때 picks[pick] -= 1 은 사용한 곡괭이의 개수를 줄이는 과정인데 DFS를 수행한 이후에는 다른 가지에 영향이 가지 않도록 다시 되돌려주어야 한다는 것을 잊으면 안된다.
'알고리즘 > PROGRAMMERS (Python)' 카테고리의 다른 글
| [ 프로그래머스 / LV2 / 파이썬 Python ] 연속된 부분 수열의 합 (0) | 2023.04.07 |
|---|---|
| [ 프로그래머스 / LV2 ] 디펜스 게임 (파이썬 Python ) (0) | 2023.04.04 |
| [ 프로그래머스 / LV3 ] 연속 펄스 부분 수열의 합 ( Python 파이썬 ) (0) | 2023.03.31 |
| [ 프로그래머스 ][ lv2 ] 뒤에 큰 수 찾기 ( 파이썬 Python ) (Stack을 사용하지 않은 풀이) (2) | 2023.03.30 |
| [ 프로그래머스 ][ Lv3 ] 인사고과 ( 파이썬 Python ) (0) | 2023.03.28 |
