๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“Š Algorithm/BOJ

โœ… BOJ 15686 - ์กฐํ•ฉ ๋ฐฑํŠธ๋ž˜ํ‚น

by huis_log 2025. 7. 2.

๋ฐฑ์ค€ 15686 ์น˜ํ‚จ ๋ฐฐ๋‹ฌ - ์กฐํ•ฉ ์™„์ „ํƒ์ƒ‰

๋ฌธ์ œ ํ•ต์‹ฌ

  • N×N ๊ฒฉ์ž์— ์ง‘(1), ์น˜ํ‚จ์ง‘(2) ์žˆ์Œ
  • ์น˜ํ‚จ ๊ฑฐ๋ฆฌ: ๊ฐ ์ง‘์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์น˜ํ‚จ์ง‘๊นŒ์ง€์˜ ๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ
  • ๋„์‹œ ์น˜ํ‚จ ๊ฑฐ๋ฆฌ: ๋ชจ๋“  ์ง‘์˜ ์น˜ํ‚จ ๊ฑฐ๋ฆฌ ํ•ฉ
  • ์น˜ํ‚จ์ง‘ ์ค‘ M๊ฐœ๋งŒ ๋‚จ๊ธฐ๊ณ  ๋‚˜๋จธ์ง€ ํ์—…
  • ๋ชฉํ‘œ: ๋„์‹œ ์น˜ํ‚จ ๊ฑฐ๋ฆฌ ์ตœ์†Œํ™”

๊ฐœ๋… ์ •๋ฆฌ

์ž˜๋ชป๋œ ์ ‘๊ทผ๋ฒ•

"๊ฑฐ๋ฆฌ ๋ฉ€์–ด์„œ ์น˜ํ‚จ์ง‘ ๋จผ์ € ์ œ๊ฑฐํ•˜๋ฉด ๋จ" → ์•„๋‹˜. ๋ฉ€์–ด๋„ ํŠน์ • ์ง‘์—๊ฒŒ๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์น˜ํ‚จ์ง‘์ผ ์ˆ˜ ์žˆ์Œ

"์น˜ํ‚จ์ง‘ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€๊นŒ์šด ์ง‘ ์ฐพ๊ธฐ" → ์•„๋‹˜. ์ง‘ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์น˜ํ‚จ์ง‘ ์ฐพ๋Š” ๋ฌธ์ œ์ž„

์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ

์กฐํ•ฉ + ์™„์ „ํƒ์ƒ‰

  • ์น˜ํ‚จ์ง‘ ์ตœ๋Œ€ 13๊ฐœ → 13CM ๊ฒฝ์šฐ์˜ ์ˆ˜ ๋งค์šฐ ์ ์Œ
  • ๋ชจ๋“  M๊ฐœ ์กฐํ•ฉ ๋‹ค ํ•ด๋ณด๋ฉด ๋จ

๊ตฌํ˜„

1. ๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ

distance = abs(x1 - x2) + abs(y1 - y2)

BFS/DFS ๊ฐ™์€ ๊ฑฐ ์“ธ ํ•„์š” ์—†์Œ. ๊ทธ๋ƒฅ ์ขŒํ‘œ ์ฐจ์ด ๊ณ„์‚ฐํ•˜๋ฉด ๋.

2. ์กฐํ•ฉ ์ƒ์„ฑ

์‹ค์ „์šฉ - itertools

from itertools import combinations
possible_combinations = combinations(chickens, m)

๊ฐœ๋… ์ดํ•ด์šฉ - ๋ฐฑํŠธ๋ž˜ํ‚น

def make_combinations(chickens, m_count):
    result = []
    selected = []

    def dfs(depth, start_idx):
        if depth == m_count:
            result.append(selected[:])
            return

        for i in range(start_idx, len(chickens)):
            selected.append(chickens[i])
            dfs(depth + 1, i + 1)
            selected.pop()  # ๋ฐฑํŠธ๋ž˜ํ‚น

    dfs(0, 0)
    return result

3. ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ

def cal_route(houses, selected_chickens):
    total = 0
    for hx, hy in houses:
        min_dist = float('inf')
        for cx, cy in selected_chickens:
            dist = abs(hx - cx) + abs(hy - cy)
            min_dist = min(min_dist, dist)
        total += min_dist
    return total

์ „์ฒด ์ฝ”๋“œ

import sys
from itertools import combinations

input = sys.stdin.readline

n, m = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(n)]

houses = []
chickens = []

for r in range(n):
    for c in range(n):
        if board[r][c] == 1:
            houses.append((r, c))
        elif board[r][c] == 2:
            chickens.append((r, c))

def cal_route(houses, selected_chickens):
    total = 0
    for hx, hy in houses:
        min_dist = float('inf')
        for cx, cy in selected_chickens:
            dist = abs(hx - cx) + abs(hy - cy)
            min_dist = min(min_dist, dist)
        total += min_dist
    return total

min_distance = float('inf')

for combo in combinations(chickens, m):
    distance = cal_route(houses, combo)
    min_distance = min(min_distance, distance)

print(min_distance)

ํ•ต์‹ฌ ์š”์•ฝ

  1. ์ขŒํ‘œ ์ €์žฅ: ์ง‘, ์น˜ํ‚จ์ง‘ ์œ„์น˜ ๊ธฐ๋ก
  2. ์กฐํ•ฉ ์ƒ์„ฑ: M๊ฐœ ์น˜ํ‚จ์ง‘ ์„ ํƒํ•˜๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ
  3. ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ: ๊ฐ ์ง‘์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์น˜ํ‚จ์ง‘๊นŒ์ง€ ๊ฑฐ๋ฆฌ
  4. ์ตœ์†Ÿ๊ฐ’: ๋ชจ๋“  ์กฐํ•ฉ ์ค‘ ์ตœ์†Œ ๋„์‹œ ์น˜ํ‚จ ๊ฑฐ๋ฆฌ

์น˜ํ‚จ์ง‘ ์ตœ๋Œ€ 13๊ฐœ๋ผ์„œ ์™„์ „ํƒ์ƒ‰ ๊ฐ€๋Šฅ. ๋ณต์žกํ•˜๊ฒŒ ์ƒ๊ฐํ•˜์ง€ ๋ง๊ณ  ๊ทธ๋ƒฅ ๋‹ค ํ•ด๋ณด๋ฉด ๋จ.

๋ฐ˜์‘ํ˜•