(ํŒŒ์ด์ฌ) ๋ฐฑ์ค€ 4991๋ฒˆ : ๋กœ๋ด‡ ์ฒญ์†Œ๊ธฐ

์ตœ๊ทผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋Œ€ํšŒ ๋“ฑ์— ๋‚˜๊ฐ”์„ ๋•Œ ์–ด๋ ค์šด ๋ฌธ์ œ๋ฅผ ์•Œ์•„๋ณด๋Š”๊ฒƒ์— ๋Œ€ํ•œ ์ค‘์š”์„ฑ์„ ๋А๊ผˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐฑ์ค€ ๋ฌธ์ œ๋ณ„ ๋“ฑ๊ธ‰ํ‘œ์‹œ๋ฅผ ๊บผ๋’€๋”๋‹ˆ... ์ด ๋ฌธ์ œ๊ฐ€ ๊ฑธ๋ ธ๋‹ค... ์ข‹์€๊ฑด์ง€ ์•ˆ์ข‹์€๊ฑด์ง€...



๋ฌธ์ œ 

 

https://www.acmicpc.net/problem/4991

 

๋ฌธ์ œ ์ดํ•ด

 

- w x h ์˜ ๊ฒฉ์žํŒ์ด ์ฃผ์–ด์ง

- ๋กœ๋ด‡์ฒญ์†Œ๊ธฐ๊ฐ€ ๊ฐ€๊ตฌ๋ฅผ ํ”ผํ•ด ๋”๋Ÿฌ์šด ๊ณณ์„ ์ฒญ์†Œ

- ๋”๋Ÿฌ์šด ์นธ์„ ๋ชจ๋‘ ์ฒญ์†Œํ–ˆ์„ ๋•Œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋Š”?  -> ์™ธํŒ์› ์ˆœํšŒ ๋ฌธ์ œ์ด๋‹ค. ์•„๋งˆ ์ด์ „์— ํ’€์—ˆ๋˜ 2098๋ฒˆ๊ณผ ๋น„์Šทํ•  ๋“ฏ..

- ๋”๋Ÿฌ์šด ์นธ์€ 10๊ฐœ ์ดํ•˜ -> ๋น„ํŠธ๋งˆ์Šคํ‚น์„ DP ์ธ๋ฑ์Šค์— ์‚ฌ์šฉํ•œ๋‹ค (๋ฐฉ๋ฌธํ•œ ์ƒํ™ฉ, ์ง์ „ ๋ฐฉ๋ฌธํ•œ ์œ„์น˜)

 

์ฝ”๋“œ ์„ค๋ช…

 

- ์ผ๋‹จ ๋”๋Ÿฌ์šด ์นธ์„ ์ „๋ถ€ ๋ชจ์•„๋‘๊ณ  ๊ฐ๊ฐ์„ ์‹œ์ž‘์œผ๋กœ bfs๋ฅผ ๋Œ๋ฆฐ๋‹ค

- ๊ฐ ์นธ์—์„œ ๋‹ค๋ฅธ ์นธ์œผ๋กœ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ์ €์žฅํ•ด๋‘์ž. 

   - ๋งŒ์•ฝ bfs ๋Œ๋ ธ์„๋•Œ -1์ด ๋‚˜์™”๋‹ค๋ฉด? ์–ด๋–ป๊ฒŒ์„œ๋“  ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” ์นธ์ด ๋‚˜์˜จ ๊ฒƒ -> return -1๋กœ ๋๋‚ธ๋‹ค.

  -> dist_remove๋Š” {0:{1:2,2:4,3:4,4:5,...},{},..} ์ด๋Ÿฐ ์‹์œผ๋กœ 0์—์„œ ์ถœ๋ฐœํ•ด 3์œผ๋กœ ๊ฐ€๋Š”๊ฑด ๊ฑฐ๋ฆฌ 4.

 

=> ๋”๋Ÿฌ์šด ์นธ์˜ ์‚ฌ์ด ๊ฑฐ๋ฆฌ๋“ค์„ ์ „๋ถ€ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. (dist_remove)

 

- ๊ทธ ๋‹ค์Œ์€ DP๋กœ ์ „๋ถ€ ๋ฐฉ๋ฌธํ–ˆ์„๋•Œ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ๋‹ค.

- dp [์ฒญ์†Œํ•ด์•ผํ•˜๋Š” ์นธ์˜ ์ˆ˜๋งŒํผ 2์˜ ์ œ๊ณฑ] [์ฒญ์†Œํ•ด์•ผํ•˜๋Š” ์นธ์˜ ์ˆ˜ <-์ง์ „ ์ฒญ์†Œํ•œ๊ณณ] = ์ „๋ถ€ INF

- ๊ฐฑ์‹ ํ•ด๊ฐ€๋ฉด์„œ ์ตœ์ข…์ ์œผ๋กœ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๊ตฌํ•จ.
dp
[mask | (1 << v)][v] = min( dp[mask | (1 << v)][v], dp[mask][u] + dist_remove[u][v] )

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import sys
from collections import deque
 
input = sys.stdin.readline
 
dir = [[-10], [10], [0-1], [01]]
 
 
def valid(x, y):
    return 0 <= x < h and 0 <= y < w
 
 
def bfs(start):
    dist = [[-1* w for _ in range(h)]
    queue = deque([start])
    dist[start[0]][start[1]] = 0
 
    while queue:
        x, y = queue.popleft()
        for dx, dy in dir:
            xx, yy = x + dx, y + dy
            if valid(xx, yy) and G[xx][yy] != "x" and dist[xx][yy] == -1:
                dist[xx][yy] = dist[x][y] + 1
                queue.append((xx, yy))
 
    return dist
 
 
def solve(w, h):
    dirty_box = []
    start = None
 
    for i in range(h):
        for j in range(w):
            if G[i][j] == "*":
                dirty_box.append((i, j))
            elif G[i][j] == "o":
                start = (i, j)
 
    dirty_box.insert(0, start)
    remove_num = len(dirty_box)
    dist_remove = [[0* remove_num for _ in range(remove_num)]
    for i in range(remove_num):
        sx, sy = dirty_box[i]
        short_paths = bfs((sx, sy))  # i ์ถœ๋ฐœ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋“ค
        for j in range(remove_num):  # i์™€ j ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋“ค
            if i != j:
                tx, ty = dirty_box[j]
                if short_paths[tx][ty] == -1:
                    return -1
                dist_remove[i][j] = short_paths[tx][ty]
 
    # DP
    INF = float("inf")
    dp = [[INF] * remove_num for _ in range(1 << remove_num)]  # ๋น„ํŠธ๋งˆ์Šคํ‚น
    dp[1][0= 0
   #dirty_box์˜ ์ฒซ๋ฒˆ์งธ๋Š” ์Šคํƒ€ํŠธ์œ„์น˜. 0000...01. ์ฒซ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋Š” ํ˜„์žฌ ์ƒํƒœ. ๋‘๋ฒˆ์žฌ ์ธ๋ฑ์Šค๋Š” ๊ทธ ์ „์˜ ์œ„์น˜
 
    for mask in range(1 << remove_num):
        for u in range(remove_num):
            if mask & (1 << u):  # u ๋ฐฉ๋ฌธํ•จ
                for v in range(remove_num):
                    if not (mask & (1 << v)):  # v๋Š” ๋ฐฉ๋ฌธ์•ˆํ•จ -> u ํ›„ v๋ฅผ ๋ฐฉ๋ฌธํ• ๋•Œ
                        dp[mask | (1 << v)][v] = min(
                            dp[mask | (1 << v)][v], dp[mask][u] + dist_remove[u][v]
                        )
 
    result = INF
    final_mask = (1 << remove_num) - 1
    for i in range(1, remove_num):
        result = min(result, dp[final_mask][i])
 
    return result if result != INF else -1
 
 
ans = []
while True:
    w, h = map(int, input().split())
    if w == 0 and h == 0:
        break
    G = [list(input().strip()) for _ in range(h)]
 
    ans.append(str(solve(w, h)))
print("\n".join(ans))
 
cs