카카오 블라인드 채용

[카카오] 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년 2월 11일 일요일 – Mountain View 생활 122주차

유럽 여행 2주간 대학 친구와 유럽여행을 다녀왔다. 런던 출장외에 유럽 여행은 완전 처음이었는데, 좋았던 점이…

3개월 ago

2024년 1월 14일 일요일 – Mountain View 생활 118주차

Layoff 이번 주에 또 한차례 Layoff가 있었다. 작년 1월 대규모 Layoff 이후 1년만의 일이다. 새벽…

4개월 ago

2024년 1월 7일 일요일 – Mountain View 생활 117주차

2023 회고 큰 성공을 만든 건 없지만, 작년에 달성한 것들을 모아보자면 일단 잘리지 않고 해고를…

4개월 ago

2023년 12월 31일 일요일 – Mountain View 생활 116주차

영주권 매일 아침 USPS 이메일과 USCIS 앱을 열어보면서 기다리던 영주권이 드디어 발급되었다. 오늘 드디어 새로…

4개월 ago

2023년 11월 19일 일요일 – Mountain View 생활 110주차

TL;DR 이 일기는 OKR 설정의 어려움, 효과적인 마케팅 전략의 필요성, 가족 중심의 삶과 이민자로서의 경력…

5개월 ago

2023년 11월 12일 일요일 – Mountain View 생활 109주차

TL;DR 미국 생활에 찾아온 작은 변화와 가족과의 여행 소소한 행복, 그리고 AI 기술의 급속한 발전…

6개월 ago

This website uses cookies.