ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [λ°±μ€€] 17485 μ§„μš°μ˜ 달 μ—¬ν–‰ (Large) with Python
    PS 2022. 6. 4. 01:03
    728x90
    λ°˜μ‘ν˜•

    πŸ“Œ BOJ 17485 μ§„μš°μ˜ 달 μ—¬ν–‰ (Large)

    πŸ’‘ 쑰건

    1. 지ꡬ와 μš°μ£Όμ‚¬μ΄λŠ” N X M ν–‰λ ¬λ‘œ λ‚˜νƒ€λ‚Ό 수 있으며 각 μ›μ†Œμ˜ 값은 μš°μ£Όμ„ μ΄ κ·Έ 곡간을 지날 λ•Œ μ†Œλͺ¨λ˜λŠ” μ—°λ£Œμ˜ 양이닀.
      N, M (2 ≤ N, M ≤ 1000), 각 ν–‰λ ¬μ˜ μ›μ†Œκ°’μ€ 100 μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€.

     

    1. 지ꡬ -> λ‹¬λ‘œ κ°€λŠ” 경우 μš°μ£Όμ„ μ΄ 움직일 수 μžˆλŠ” λ°©ν–₯은 μ•„λž˜μ™€ κ°™λ‹€.

     

    1. μš°μ£Όμ„ μ€ 전에 움직인 λ°©ν–₯으둜 움직일 수 μ—†λ‹€. 즉, 같은 λ°©ν–₯으둜 λ‘λ²ˆ μ—°μ†μœΌλ‘œ 움직일 수 μ—†λ‹€.
      μ§„μš°μ˜ λͺ©ν‘œλŠ” μ—°λ£Œλ₯Ό μ΅œλŒ€ν•œ 아끼며 μ§€κ΅¬μ˜ μ–΄λŠμœ„μΉ˜μ—μ„œλ“  μΆœλ°œν•˜μ—¬ λ‹¬μ˜ μ–΄λŠμœ„μΉ˜λ“  μ°©λ₯™ν•˜λŠ” 것이닀.
    1. μ΅œλŒ€ν•œ λˆμ„ 아끼고 μ‚΄μ•„μ„œ 달에 λ„μ°©ν•˜κ³  싢은 μ§„μš°λ₯Ό μœ„ν•΄ 달에 λ„λ‹¬ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ μ—°λ£Œμ˜ μ΅œμ†Œκ°’μ„ κ³„μ‚°ν•˜λŠ” 문제
    1. λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°, 완전탐색 μœ ν˜•μ˜ 문제

    πŸ–₯ μ†ŒμŠ€ μ½”λ“œ

    from sys import stdin, setrecursionlimit
    
    setrecursionlimit(2000)
    
    
    def visit_tf(pos, cur_direction, next_direction):
        x, y = pos
        return cur_direction != next_direction and 0 <= y < m
    
    
    def solve(pos, cur_pos):
        x, y = pos
        if x == n:
            return 0
    
        if dp[x][y][cur_pos] != int(1e9):
            return dp[x][y][cur_pos]
    
        for next_pos, dy in enumerate(direction):
            npx, npy = x + 1, y + dy
            if visit_tf((npx, npy), cur_pos, next_pos):
                data = solve((npx, npy), next_pos) + arr[x][y]
                dp[x][y][cur_pos] = min(data, dp[x][y][cur_pos])
    
        return dp[x][y][cur_pos]
    
    
    if __name__ == '__main__':
        n, m = map(int, stdin.readline().split())
        arr = []
        answer = int(1e9)
        dp = [[[answer] * 3 for i in range(m)] for _ in range(n)]
    
        direction = [-1, 0, 1]
    
        for _ in range(n):
            arr.append(list(map(int, stdin.readline().split())))
    
        for i in range(m):
            for j in range(3):
                answer = min(answer, solve((0, i), j))
    
        print(answer)

    πŸ”– 예제 및 μ‹€ν–‰κ²°κ³Ό

    예제

    6 4
    5 8 5 1
    3 5 8 4
    9 77 65 5
    2 1 5 2
    5 98 1 5
    4 95 67 58

    μ‹€ν–‰κ²°κ³Ό

    29

    ⌨️ 문제 풀이

    1. μ™„μ „ 탐색과 λ‹€μ΄λ‚˜λ―Ήν”„λ‘œκ·Έλž˜λ° μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•˜μ—¬ 문제λ₯Ό ν•΄κ²°ν•œλ‹€.
    1. νƒμƒ‰ν•œ 경둜λ₯Ό λ‹€μ‹œ νƒμƒ‰ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 아이디어λ₯Ό μœ„ν•΄μ„œ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μ‚¬μš©ν•œλ‹€.
      각 곡간을 지날 λ•Œ μ΅œμ†Ÿκ°’μ„ κΈ°λ‘ν•˜κ³  μ΄μ „μ˜ 값을 μ‚¬μš©ν•˜λŠ” 방식을 μ‚¬μš©ν•˜λ©΄ λœλ‹€.
    1. μž¬κ·€ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν’€μ΄ν•œλ‹€λ©΄ 점화식을 λ§Œλ“€μ–΄λ³Ό 수 μžˆλ‹€.
      dp[r][c][cur_dir] = min(dp[r][c][cur_dir], recursive_find(next_r, next_c), next_dir) + board[r][c])
    1. (3)λ²ˆμ—μ„œ λ„μΆœν•œ 점화식을 ν†΅ν•΄μ„œ μ΅œμ†Ÿκ°’μ„ λ°˜μ˜ν•΄ λΆˆν•„μš”ν•œ 탐색을 막을 수 μžˆλ‹€.
    1. PyPy3 둜 μ œμΆœν•΄μ•Ό μ‹œκ°„μ΄ˆκ³Όκ°€ 걸리지 μ•ŠλŠ”λ‹€.
    1. setrecursionlimit 을 μ‚¬μš©ν•΄μ•Ό λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

    πŸ’Ύ 배운점

    1. 슀슀둜 ν’€μ΄ν•˜μ§€ λͺ»ν•΄ λΈ”λ‘œκ·Έ 글을 μ°Έκ³ ν•˜μ—¬ ν’€μ΄ν–ˆλ‹€.
    λ°˜μ‘ν˜•

    λŒ“κΈ€

Designed by Tistory.