N×N 게임판에 수가 적혀져 있다. 이 게임의 목표는 가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 점프를 해서 가는 것이다.
각 칸에 적혀있는 수는 현재 칸에서 갈 수 있는 거리를 의미한다. 반드시 오른쪽이나 아래쪽으로만 이동해야 한다. 0은 더 이상 진행을 막는 종착점이며, 항상 현재 칸에 적혀있는 수만큼 오른쪽이나 아래로 가야 한다. 한 번 점프를 할 때, 방향을 바꾸면 안 된다. 즉, 한 칸에서 오른쪽으로 점프를 하거나, 아래로 점프를 하는 두 경우만 존재한다.
가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 이동할 수 있는 경로의 개수를 구하는 프로그램을 작성하시오.
테이블 정의
dp[i][j] i, j에서 출발해서 끝까지 닿는 경우의 수
점화식 찾기
cur_weight = jump_map[i][j]
dp[i][j] = dp[i + cur_weight][j] + dp[i][j + cur_weight]
처음에는 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))
확실히 재귀를 배우고 나서 이 문제를 접하니까 시야가 확 넓어진 느낌이 든다.