카카오 블라인드 채용

[카카오] 2020 KAKAO BLIND RECRUITMENT 1차 풀이 – 외벽 점검

이 포스팅에서는 2020 카카오 블라인드 채용 1차 문제인 ‘외벽 점검’ 문제를 해설합니다. 본 풀이에 대한 테스트는 https://programmers.co.kr/learn/courses/30/lessons/60062에서 수행하였으며 공식 풀이와 일치하지 않을 수 있습니다.

공식 풀이는 링크를 참조하시기 바랍니다.


외벽 점검

출처 : 2020 KAKAO 블라인드 채용 온라인 1차
링크 : https://programmers.co.kr/learn/courses/30/lessons/60062
카테고리 : Dynamic
난이도 : 보통


문제 요약

시계 방향으로 weak point들이 주어지고, 프렌드들의 연료가 주어진다. 연료 1당 1의 거리를 이동할 수 있다. 모든 weak point들을 커버하기 위해 필요한 프렌드들의 최소 숫자를 구하여라.


문제 풀이

프렌즈 상태

가능한 프렌드들이 N명 이라고 할 때 N개의 비트를 통해 상태를 표현한다. 예를 들어 8명의 프렌드들이 있다고 할 때 0번, 3번, 7번 프렌드가 사용되었다고 하면 01001001로 표현할 수 있다. 정수로 나타낼 때 i번 프렌드는 2 ** i와 같은 값을 가진다고 생각할 수 있다

DP 테이블의 정의 및 초기화

DP[i][j]는 0 ~ i번째 weak point들을 프렌즈 상태 j로 커버할 때 남길 수 있는 연료의 최대값이다.

맨 처음 weak point는 그 전에 아무것도 없으므로 무조건 프렌드 한 명을 놔야만한다. 따라서 DP[i][j] = dist[k] (j = 2 ** k, k는 0 ~ 프렌드 수 – 1)가 된다.

i > 0인 경우에 대해서 DP[i][j]의 j는 i – 1번째 weak point의 어떤 상태로부터 온다. 두 가지 경우가 있다.

  • DP[i – 1][j]에서 남은 연료를 써서 i번째 weak point에 도달한다.
  • DP[i – 1][x]에서 어떤 프렌드를 새로 추가해서 weak point에 도달한다.
    • 이 때 k번째 프렌드를 추가하기 위해서 j의 k번째 비트는 반드시 1이어야 한다.
    • 이 경우 x는 j xor (2 ** k)가 된다.

위 경우들 중에서 가장 연료를 많이 남겨먹는 것이 DP[i][j]의 자리를 차지한다.

수행을 모두 마치고 난 후에 마지막 weak point의 인덱스 M에 대해 DP[M][j]의 값들 중에서 도달이 가능한 j들 중에서 비트에 존재하는 1의 갯수가 가장 적은 것이 정답이다.

회전 연산

어떤 해의 경우에는 주어진 weak point들의 0번째에서 시작하는 것이 아니라 임의의 지점에서부터 출발해서 한 바퀴를 돌아서 0번째 weak point를 커버하는 것이 더 최적인 것들도 있다.

따라서 모든 weak point들에 대해 각 지점을 출발점으로 잡고 DP를 수행한 결과들 중에서 가장 작은 값을 출력해야한다.


정답 코드

def count_people(number):
cnt = 0
while number > 0:
cnt += number % 2
number //= 2
return cnt
def process(weak, dist, dp):
K = []
for i in range(len(dist)):
K.append(2 ** i)
# initial position is always zero
dp[0][K[i]] = dist[i]
for i in range(1, len(weak)):
for j in range(len(dp[0])):
# move from previous state without adding people
if dp[i 1][j] >= weak[i] weak[i 1]:
dp[i][j] = dp[i 1][j] (weak[i] weak[i 1])
# add people from possible previous state
for k in range(len(dist)):
if j & K[k] == K[k] and dp[i 1][j ^ K[k]] >= 0:
dp[i][j] = max(dp[i][j], dist[k])
answer = len(dist) + 1
for j in range(len(dp[0])):
if dp[len(weak) 1][j] >= 0:
new_answer = count_people(j)
answer = min(answer, new_answer)
return answer != len(dist) + 1 and answer or 1
def solution(n, weak, dist):
k = 2 ** len(dist)
answer = 1
for i in range(len(weak)):
# set this position as start position
new_weak = [0] * len(weak)
pivot = weak[i]
for j in range(i, len(weak)):
new_weak[j i] = weak[j] pivot
for j in range(i):
new_weak[j + len(weak) i] = weak[j] + n pivot
# DP
dp = [[1] * k for j in range(len(new_weak))]
new_answer = process(new_weak, dist, dp)
if new_answer != 1:
answer = answer == 1 and new_answer or min(answer, new_answer)
return answer
cs

Competition 카카오 블라인드 채용 외벽 점검

admin

Recent Posts

2024년 11월 3일 일요일 – 서울 생활 127주차

반복적인 일상 매일 아침 일어나 회사에 출근하고, 저녁을 먹고 돌아오는 일상의 반복이다. 주말은 가족을 보러…

2일 ago

2024년 10월 6일 일요일 – 서울 생활 123주차

Planning A well-structured plan has the following characteristics:   First, the ultimate vision you aim to…

1개월 ago

2024년 9월 29일 일요일 – 서울 생활 122주차

English The most common problem for English learners like myself is that we often use…

1개월 ago

2024년 9월 22일 일요일 – 서울 생활 121주차

추석 추석을 맞아 친가 외가 처가 어르신들을 모두 뵙고 돌아왔다. 아이가 태어난지는 좀 됐지만 한국에서…

1개월 ago

2024년 9월 8일 일요일 – 서울 생활 119주차

주말 이번주는 아내가 올라와서 주말을 함께 보냈다. 둘만 밥도 먹고 뮤지컬도 보고, 모임도 나가고 집에서…

2개월 ago

2024년 9월 1일 일요일 – 서울 생활 118주차

여행 지난주에 코로나에 걸리는 바람에 근 3주만에 가족을 만나고 왔다. 집에 있어봐야 시간도 안가고 할…

2개월 ago

This website uses cookies.