오늘의 문제 - boj-1890

코변·2022년 11월 2일
0

알고리즘 공부

목록 보기
22/65

문제

N×N 게임판에 수가 적혀져 있다. 이 게임의 목표는 가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 점프를 해서 가는 것이다.

각 칸에 적혀있는 수는 현재 칸에서 갈 수 있는 거리를 의미한다. 반드시 오른쪽이나 아래쪽으로만 이동해야 한다. 0은 더 이상 진행을 막는 종착점이며, 항상 현재 칸에 적혀있는 수만큼 오른쪽이나 아래로 가야 한다. 한 번 점프를 할 때, 방향을 바꾸면 안 된다. 즉, 한 칸에서 오른쪽으로 점프를 하거나, 아래로 점프를 하는 두 경우만 존재한다.

가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 이동할 수 있는 경로의 개수를 구하는 프로그램을 작성하시오.

풀이

  1. 테이블 정의
    dp[i][j] i, j에서 출발해서 끝까지 닿는 경우의 수

  2. 점화식 찾기

cur_weight = jump_map[i][j]
dp[i][j] = dp[i + cur_weight][j] + dp[i][j + cur_weight]

  1. 초기값 설정
    dfs를 사용하기 때문에 방문여부를 저장할 필요가 있다. dp를 -1로 모두 초기화를 해준다 (0으로 초기화하면 실제 0인 값을 구할 수 없음)

처음에는 dp[i][j]테이블을 0, 0에서 i, j로 갈 수 있는 경로의 수로 정의해서 풀려고 했으나 재귀로 테이블 값을 구하려고 하니까 시간초과가 났다.

만약 기존의 조건으로 테이블을 정의하려면 이중 for문으로 O(N**2)으로 구할 수 있을 것 같다.

import sys
input = sys.stdin.readline

N = int(input().rstrip())

jump_map = [list(map(int, input().rstrip().split())) for _ in range(N)]
dp = [[-1] * N for _ in range(N)]

def get_path(r,c):
    if r == N-1 and c == N-1:
        return 1
    if r >= N or c >= N:
        return 0
    if dp[r][c] == -1:
        dp[r][c] = 0
        
        cur_weight = jump_map[r][c]
        next_r = r + cur_weight
        next_c = c + cur_weight
        if next_r < N:
            dp[r][c] += get_path(next_r, c)
        if next_c < N:
            dp[r][c] += get_path(r, next_c)

    return dp[r][c]

print(get_path(0,0))

피드백

확실히 재귀를 배우고 나서 이 문제를 접하니까 시야가 확 넓어진 느낌이 든다.

profile
내 것인 줄 알았으나 받은 모든 것이 선물이었다.

0개의 댓글