정리와기록 블로그

[1890] 점프 본문

BOJ/동적계획법

[1890] 점프

뫂림 2020. 4. 4. 10:22

문제: https://www.acmicpc.net/problem/1890

 

1890번: 점프

문제 N×N 게임판에 수가 적혀져 있다. 이 게임의 목표는 가장 왼쪽 위 칸에서 가장 오른쪽 아래 칸으로 규칙에 맞게 점프를 해서 가는 것이다. 각 칸에 적혀있는 수는 현재 칸에서 갈 수 있는 거리를 의미한다. 반드시 오른쪽이나 아래쪽으로만 이동해야 한다. 0은 더 이상 진행을 막는 종착점이며, 항상 현재 칸에 적혀있는 수만큼 오른쪽이나 아래로 가야 한다. 한 번 점프를 할 때, 방향을 바꾸면 안 된다. 즉, 한 칸에서 오른쪽으로 점프를 하거나, 아래로

www.acmicpc.net

 

접근:

  • 기저 사례는 총 세 개로, (N-1,N-1)을 밟는 경우 / 범위를 넘어가는 경우 / 중간 단계에서 0을 밟는 경우 이다.
  • 기저 사례는 (N-1,N-1)을 밟는 경우 -> 범위를 넘어간는 경우 -> 중간 단계에서 0을 밟는 경우 순서대로 처리한다.
  • y,x를 받아 N,M까지 가는 경우의 수를 반환하는 형태의 재귀 + bottom up 방식으로 DP 함수를 구현했다.
  • 경우의 수가 2^63-1까지 가므로, int 자료형이 아니라 long long 자료형을 사용했다.

 

코드:

#include <iostream>
#include <memory.h>

using namespace std;

typedef long long dl;
int N;
int map[101][101];
dl cache[100][100];

dl findPath(int y, int x)
{
	if (y == N - 1 && x == N - 1) return 1;
	if (y >= N || x >= N) return 0;
	if (!map[y][x]) return 0;
	
	dl& ret = cache[y][x];
	if (ret != -1) { return ret; }

	return ret = findPath(y, x + map[y][x]) + findPath(y + map[y][x], x);
}

int main()
{
	ios::sync_with_stdio(false);
	memset(cache, -1, sizeof(cache));

	cin >> N;
	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)
			cin >> map[i][j];

	cout << findPath(0, 0) << "\n";

	return 0;
}

'BOJ > 동적계획법' 카테고리의 다른 글

[12865] 평범한 배낭  (0) 2020.09.19
[10835] 카드게임  (0) 2020.09.01
[10942] 팰린드롬?  (0) 2020.04.04
[11055] 가장 큰 증가 부분 수열  (0) 2020.03.07
[14002] 가장 긴 증가하는 부분 수열 4  (0) 2020.03.07
Comments