출처 : https://www.acmicpc.net/problem/15686
풀이 방법
M개의 치킨 집을 선택하는 과정에서 순서에 상관없는 조합을 이용해야 한다.
조합을 구하기 위해 백트레킹 dfs를 사용했다.
아래의 코드에서 chosen 배열에 넣은 후 dfs를 수행하고 chosen배열에서 pop을 통해 백 트레킹을 수행했다.
치킨 거리 계산은 그냥 유클리드 계산으로 수행하면 된다.
N, M = map(int, input().split()) ## N, M 입력받기
city = []
for i in range(N): ## city 입력 받기
city.append(input().split())
house = []
store = []
chosen = []
ans = 987654321
for i in range(N): ## 치킨 집과 집을 저장한다.
for j in range(N):
if city[i][j] == '1':
house.append([i, j])
elif city[i][j] == '2':
store.append([i, j])
def distance(a, b, x, y): ## 유클리드 거리를 계산한다.
return abs(a - x) + abs(b - y)
def cal_dis(): ## 현재의 최소 치킨 거리를 계산한다.
ret = 0
for i, j in house: ## 모든 집을 돌며
min_dis = 987654321 ## 현재 집에서의 최소 치킨집 까지의 거리
for k in chosen: ## 선택된 치킨 집
min_dis = min(min_dis, distance(i, j, store[k][0], store[k][1]))
ret += min_dis ## 현재집에서 가장 작은 치킨 집 거리 계산
return ret
def dfs(idx, cnt): ## 현재 치킨 집 idx, 치킨 집 수, 지금 까지의 거리
global ans
if cnt == M: ## 만약 M개의 치킨 집이 선택이 되었으면 치킨 거리 계산하는 로직 수행
ans = min(ans, cal_dis())
return
for i in range(idx + 1, len(store)): ##
chosen.append(i) ## i 번째 더하기
dfs(i, cnt + 1)
chosen.pop() ## i 번째 빼기
return
for i in range(len(store)): ## N-1 까지 잖아
chosen.append(i) ## i 번째 더하기
dfs(i, 1)
chosen.pop() ## i 번째 빼기
print(ans)
'Algorithm' 카테고리의 다른 글
[백준] 암호 코드 2011번 (python) DP (0) | 2024.08.18 |
---|---|
[백준] ACM Craft 1005번 (python) 위상정렬 + dp (0) | 2024.08.04 |
[백준] 줄 세우기 2252 (python) 위상정렬 (0) | 2024.07.28 |
[백준] 전깃줄 2565번 (python) LSB (1) | 2024.07.20 |
[백준] 학교 탐방하기 (python) (0) | 2024.07.15 |