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 |