일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 서브쿼리
- 다이나믹프로그래밍
- 시뮬레이션
- DFS
- 그래프 탐색
- 에라토스테네스의 체
- 트리
- 분할정복
- 투포인터
- join
- 다시
- BFS
- 그리디
- 백트래킹
- 크루스칼
- 구현
- 누적합
- 브루트포스
- 해시
- 수학
- DP
- 우선순위큐
- MST
- 재귀
- 다이나믹 프로그래밍
- GROUP BY
- 다익스트라
- 자료구조
- 그래프 이론
- 플로이드-워셜
- Today
- Total
기록하고 까먹지 말기
15686 본문
날짜 : 2023. 05. 04
사용 언어 : python
문제

코드
import sys
from itertools import combinations
n, m = map(int, sys.stdin.readline().split())
graph = list()
house = list() # 집의 좌표
chicken = list() # 치킨집 좌표
for _ in range(n):
graph.append(list(map(int, sys.stdin.readline().split())))
for i in range(n): # 최대 2500
for j in range(n):
if graph[i][j] == 1:
house.append([i, j])
elif graph[i][j] == 2:
chicken.append([i, j])
res = int(1e9) # 도시의 치킨거리
for pick in combinations(chicken, m): # 모든 치킨집 중에서 m개 뽑은 케이스 -> 최대 13C5 *
temp = 0
for h in house:
d = 10000 # 하나의 가구의 치킨거리
for p in pick:
d = min(d, abs(h[0]-p[0]) + abs(h[1]-p[1]))
temp += d
res = min(res, temp)
print(res)
풀이
- 치킨집, 가정집의 좌표를 각 리스트에 저장
- combinations를 활용해 전체 치킨집 중에서 m 개를 추출 -> pick
- 하나의 가정집을 토대로 pick한 치킨집에 대한 최소 치킨거리를 구한다.(하나의 가구 대한 치킨거리)
- 이를 temp 에 더한 후 모든 가정집에 대한 치킨거리 총합이 구해졌다면 이 값을 토대로 도시의 치킨거리의 최소값을 최신화한다.
알게된 점
- 시간복잡도를 고려해서 BFS로 구해볼까 했는데 너무 복잡해져서 다른사람의 풀이를 참고했고, combination으로 풀이하는 것을 알게 되었다.
- combination으로 m개를 뽑은 케이스를 만들면 이 케이스를 토대로 도시의 치킨거리를 구할 수 있다.
- 그리고 이 치킨거리를 모든 경우의수를 비교하면서 최소값으로 갱신하는 원리였다.
- 풀이 이후 시간복잡도를 구해보았는데 각각 2 ≤ N ≤ 50, 1 ≤ M ≤ 13 이었기 때문에 이중 for문에서는 50*50 = 2500, 3중 for문에선 O(13C6*2N*13) < 100,000,000 이었다. 그래서 combination을 활용한 브루트포스가 가능했던 것 같다.
참고 사이트
- https://codesyun.tistory.com/185
[BOJ / 백준] 15686번 치킨 배달 파이썬(Python) 문제 풀이
문제 문제 링크 : https://www.acmicpc.net/problem/15686 15686번: 치킨 배달 크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은
codesyun.tistory.com