매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.
섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다.Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.
scoville | K | return |
---|---|---|
[1, 2, 3, 9, 10, 12] | 7 | 2 |
모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다.
heapq
라이브러리를 이용한다.💡음식을 섞다가 하나만 남는 경우를 주의해야함!
def solution(scoville, K):
import heapq
scoville_heap = scoville[:]
heapq.heapify(scoville_heap)
mix_cnt = 0
while len(scoville_heap) > 1 and scoville_heap[0] < K:
first = heapq.heappop(scoville_heap)
second = heapq.heappop(scoville_heap)
mix = first + second * 2
heapq.heappush(scoville_heap, mix)
mix_cnt += 1
return mix_cnt if scoville_heap[0] >= K else -1
import heapq
heapq.heapify(L) # 리스트 L을 min heap 으로 구성
heapq.heappop(L) # min heap L로부터 최소값 삭제 및 반환
heapq.heappush(L, item) # min heap L에 item 삽입
동적계획법
주어진 최적화 문제를 재귀적인 방식으로 보다 작은 부분 문제로 나누어
부분 문제를 풀어, 이 해를 조합하여 전체 문제의 해답에 이르는 방식
알고리즘의 진행에 따라 탐색해야 할 범위를 동적으로 결정함으로써 탐색 범위를 한정할 수 있음
문제의 성질에 따라, 동적계획법으로 풀어냄으로써 탐색해야 하는 범위를 효과적으로 줄일 수 있음!
아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)12 = 55 / 5 + 5 / 512 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
N | number | return |
---|---|---|
5 | 12 | 4 |
2 | 11 | 3 |
예제 #1
문제에 나온 예와 같습니다.
예제 #2
11 = 22 / 2
와 같이 2를 3번만 사용하여 표현할 수 있습니다.
def solution(N, number):
dp = [set([int(str(N) * i)]) for i in range(1, 9)]
for i in range(len(dp)):
for j in range(i):
for op1 in dp[j]:
for op2 in dp[i - j - 1]:
dp[i].add(op1 + op2)
dp[i].add(op1 - op2)
dp[i].add(op1 * op2)
if op2 != 0:
dp[i].add(op1 // op2)
if number in dp[i]:
return i + 1
return -1
주어진 항공권을 모두 이용하여 여행경로를 짜려고 합니다. 항상 ICN 공항에서 출발합니다.
항공권 정보가 담긴 2차원 배열 tickets가 매개변수로 주어질 때, 방문하는 공항 경로를 배열에 담아 return 하도록 solution 함수를 작성해주세요.
tickets | return |
---|---|
[[ICN, JFK], [HND, IAD], [JFK, HND]] | [ICN, JFK, HND, IAD] |
[[ICN, SFO], [ICN, ATL], [SFO, ATL], [ATL, ICN], [ATL,SFO]] | [ICN, ATL, ICN, SFO, ATL, SFO] |
예제 #1
[ICN, JFK, HND, IAD] 순으로 방문할 수 있습니다.
예제 #2
[ICN, SFO, ATL, ICN, ATL, SFO] 순으로 방문할 수도 있지만 [ICN, ATL, ICN, SFO, ATL, SFO] 가 알파벳 순으로 앞섭니다.
재귀적인 성질을 가진 "한 붓 그리기" 문제
→ 재귀적인 성질을 가진 깊이 우선 탐색(DFS)를 응용하여 해결
def solution(tickets):
from collections import defaultdict
dd = defaultdict(list)
for k, v in tickets:
dd[k].append(v)
for k, v in dd.items():
dd[k].sort(reverse=True)
stack, path = ['ICN'], []
while stack:
start = stack[-1]
if len(dd[start]) == 0:
path.append(stack.pop())
else:
stack.append(dd[start].pop())
return path[::-1]