본문 바로가기

백준

백준1890 - 점프

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

 

1890번: 점프

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

www.acmicpc.net

오랜만에 다이나믹 프로그래밍 문제를 풀었다. 탐색으로는 도저히 풀 수 있는 방법이 없었고 이동 가능한 방향이 오른쪽과 아래로 주어져 있기 때문에 다이나믹 프로그래밍으로 접근하였다. 현재 위치에서 갈 수 있는 거리가 주어지고 그 거리가 유효한 좌표 범위이면 도달 가능하다고 구하였다. 중요한 것은 도달할 수 없는 곳은 건너뛴다는 것이다. 또한 마지막 도착점은 0으로 주어지기 때문에 도착점에서 다이나믹 프로그래밍을 이용하여 비용을 구하면 잘못된 비용이 나오기 때문에 도착점을 건너뛴다는 것도 중요하다.

 

#include <iostream>
#define MAX 101
using namespace std;

int n; //정사각형 한 변의 길이
int mat[MAX][MAX] = { 0 }; //(x, y)에서 이동해야 되는 거리
long long int d[MAX][MAX] = { 0 }; //(x, y)에 도달할 수 있는 방법의 수

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> mat[i][j];
		}
	}

	d[1][1] = 1; //출발지점은 1로 설정

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (d[i][j] == 0 || (i == n && j == n)) { //도착할 수 없는 곳이나 마지막 칸을 만나면
				continue; //무시
			}
			if (1 <= i + mat[i][j] && i + mat[i][j] <= n) { //현재 위치에서 행 방향으로 도달할 수 있는 곳이면
				d[i + mat[i][j]][j] += d[i][j]; //가려하는 곳의 방법의 수를 현재 위치에 도달할 수 있는 방법과 더한다.
			}
			if (1 <= j + mat[i][j] && j + mat[i][j] <= n) { //현재 위치에서 열 방향으로 도달할 수 있는 곳이면
				d[i][j + mat[i][j]] += d[i][j]; //가려하는 곳의 방법의 수를 현재 위치에 도달할 수 있는 방법과 더한다.
			}
		}
	}

	cout << d[n][n];
}

'백준' 카테고리의 다른 글

백준12101 - 1, 2, 3 더하기 2  (0) 2020.03.30
백준2491 - 수열  (0) 2020.03.29
백준1041 - 주사위  (0) 2020.03.26
백준14889 - 스타트와 링크  (0) 2020.03.22
백준2573 - 빙산  (0) 2020.03.22