Algorithm/Algospot
[ID: JUMPGAME] 외발 뛰기
마산와사비
2019. 12. 30. 16:43
algospot.com :: JUMPGAME
외발 뛰기 문제 정보 문제 땅따먹기를 하다 질린 재하와 영훈이는 땅따먹기의 변종인 새로운 게임을 하기로 했습니다. 이 게임은 그림과 같이 n*n 크기의 격자에 각 1부터 9 사이의 정수를 쓴 상태로 시작합니다. 각 차례인 사람은 맨 왼쪽 윗 칸에서 시작해 외발로 뛰어서 오른쪽 아래 칸으로 내려가야 합니다. 이 때 각 칸에 적혀 있는 숫자만큼 오른쪽이나 아래 칸으로 움직일 수 있으며, 중간에 게임판 밖으로 벗어나면 안 됩니다. 균형을 잃어서 다른 발로 서거
algospot.com
- 풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static int T = 0;
private static int N = 0;
private static int[][] cache;
private static int[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
T = Integer.parseInt(br.readLine()); // TestCase
StringTokenizer st;
for(int t = 0; t < T; t++) {
N = Integer.parseInt(br.readLine());
cache = new int[N+1][N+1];
map = new int[N+1][N+1];
for(int y = 0; y < N; y++) {
st = new StringTokenizer(br.readLine());
for(int x = 0; x < N; x++) {
cache[y][x] = -1;
map[y][x] = Integer.parseInt(st.nextToken());
}
}
int ans = jump(0, 0);
System.out.println(ans == 1 ? "YES" : "NO");
}
}
public static int jump(int y, int x) {
if(y >= N || x >= N) return 0;
if(y == N-1 && x == N-1) return 1;
int ret = cache[y][x];
if(ret != -1) {
return ret;
}
int jumpSize = map[y][x];
boolean ret1 = jump(y+jumpSize, x) == 1 ? true : false;
boolean ret2 = jump(y, x+jumpSize) == 1 ? true : false;
return cache[y][x] = (ret1 || ret2 == true) ? 1 : 0;
}
}
- NOTE
- Java에서는 int 자료형을 논리형으로 인식하지 못하므로 변환 과정이 필요.
- 동적계획법 적용시, 다음과 같은 순서로 적용한다.
- 주어진 문제를 완전 탐색을 이용해 해결
- 중복된 부분 문제를 한 번만 계산하도록 메모이제이션을 적용
메모이제이션 구현 패턴
메모이제이션을 적용하기 위해서는 반드시 참조적 투명함수(referential trasparent function)여야 한다.
- 참조적 투명함수(referential transparent function)란?
- 참조적 투명성(referential transparent)이 지켜지는 함수
- 함수의 반환값이 입력값으로만 결정되는 함수
- 입력이 고정되어 있을 때 그 결과가 항상 같아야 한다.
function()이 한 번 계산하는데 굉장히 시간이 오래 걸리는 참조적 투명 함수라고 가정하는 경우, 메모이제이션 구현 패턴은 아래와 같다.
- 항상 기저 사례를 제일 먼저 처리. 입력이 범위를 벗어난 경우를 기저 사례로 처리하면 매우 유용
- 함수의 반환 값이 항상 0이라는 점을 이용하여 cache[]를 모두 -1로 초기화. cache[]의 해당 위치에 적혀 있는 값이 -1이라면 이 값은 아직 계산이 되지 않은 값임을 의미한다. 만약 함수의 반환 값이 음수일 수 있다면 이 방법은 사용 불가.
참고 - 프로그래밍 대회에서 배우는 알고리즘 문제해결 전략