TIL
99클럽 TIL (240829)
wnwlals13
2024. 8. 29. 15:19
> [Middler] 광물 캐기
https://school.programmers.co.kr/learn/courses/30/lessons/172927#
🔥다시보기🔥
문제 풀이 과정
처음에 문제를 잘못읽어서 곡괭이를 순차적으로 골랐는데, 그게 아니었다. 그래서 모든 곡괭이에서 광물을 캐는 DFS를 생각했다.
아쉽게도 DFS로도 문제를 해결하지 못했다.
💩 틀린 문제 풀이
큐에 넣고 현재 곡괭이에서 미네랄을 캔 모든 경우를 answer에 담는 로직을 구현하려고 했다... 하지만 시간도 너무 지체되고 문제가 풀리지 않았다.
def addTired(pick, mineral, num) :
if pick == 0 :
num[pick] += 1
elif pick == 1 :
if mineral == "diamond" :
num[pick] += 5
else :
num[pick] += 1
else :
if mineral == "diamond" :
num[pick] += 25
elif mineral == "iron" :
num[pick] += 5
else :
num[pick] += 1
def solution(picks, minerals):
answer = [0] * len(picks)
q = []
for i in range(len(picks)) :
if picks[i] != 0 :
v = [False] * len(minerals)
q.append((i, picks[i] * 5, v))
while q :
pick, pCnt, v = q.pop()
if pCnt == 0 :
continue
print(pick,pCnt,v, answer)
for j, m in enumerate(minerals) :
if not v[j] and pCnt > 0 :
pCnt -= 1
addTired(pick, m, answer)
v[j] = True
if pick == len(picks)-1 :
q.append((0, pCnt, v))
else :
q.append((pick+1, pCnt, v))
return min(answer)
문제 풀이
DFS 풀이
- 참조 : https://toki0411.tistory.com/80
- ✨ 기억할것!
- 조건문으로 바로 구현하기보다 그래프로 생각해보기! (광물 피로도 표)
- 재귀, 반복의 경우 base condition을 통해 재귀를 탈출시켜야 한다. 조건을 잘 기입하자!
def solution(picks, minerals):
answer = []
tired = [[1,1,1],[5,1,1],[25,5,1]]
mineralCol = {"diamond" : 0, "iron" : 1, "stone" : 2}
def dfs(picks, minerals, value) :
# 곡괭이를 다쓰면 리턴
if sum(picks) == 0 or len(minerals) == 0:
answer.append(value)
return
m = minerals[:5]
for i in range(3) :
if picks[i] > 0 :
picks[i] -= 1
pVal = 0
for j in m :
pVal += tired[i][mineralCol[j]]
dfs(picks, minerals[5:], value+pVal)
picks[i] += 1
dfs(picks, minerals, 0)
return min(answer)
그리디
- 참조 : 블로그 (ㅠ글이해하기)
- 그리디 알고리즘으로 푸는 게 더 효과적이다. 5개씩 다이아몬드, 철, 곡괭이를 사용했을 때 피로도를 계산해 놓으면 돌 곡괭이를 사용했을 때를 기준으로 내림차순 정렬하면 최선의 경우의 수를 찾을 수 있다.
- 이렇게 해결할 수 있는 이유는 돌, 철, 다이아몬드를 비교했을 때 효율이 차이나기 때문이다. 무조건 철 곡괭이가 돌보다 효율이 높고, 다이아몬드가 곡괭이가 철보다 효율이 높다. 따라서 전부 탐색할 필요없이 다이아몬드, 철, 돌 순대로 나열하고 다이아몬드, 철, 돌 곡괭이가 있는 대로 적용하면 된다.
회고 및 느낀점
그리디 문제는 여전히 어렵다...😢