Algorithm, boj, 내리막길(1520)

틀린이유와 풀이

  • boolean[][] visitied을 이용해서 일반 dfs로 풀어주면 타임아웃이 발생한다
  • dp[i][j] = (i,j)지점에서 끝까지 갈수있는 경로 개수로 지정해서 메모이제이션을 이용할것
  • ex) dp[2][3] = 1이라면 2,1->2,2->2,3 에 도착할때 2,3지점에서 끝까지 갈수있는 경로는 이미 1개 있으니까 return dp[2][3]해준다
  • 모든 경로의 수를 더해주면 끝.

주의

  • 내리막길로 이동하다가 더이상 내리막길이 없어 중간에 멈추는 경우가 생길 수 있는데
  • 이 때 dp값은 0이 되어야 할 것입니다. (갈 수있는 경로가 0개이다)
  • 그런데 dp 초기값을 0으로 설정한 경우, 가기를 시도한 경로인지, 갈 수가 없는 경우인지 구분 할 수 없어 memoization을 하지 못하고 다시 연산을 하므로 시간이 초과 된다
  • 따라서 dp 초기값을 위 경우(0)를 처리할 수 있는 값으로 설정해야 한다. (예: -1)
package org.baekjoon;

import java.util.Scanner;

public class test1520_dp_downhill {

	static int m,n;
	static int[][] arr,dp;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		m = sc.nextInt();
		n = sc.nextInt();
		arr = new int[m][n];
		dp = new int[m][n];
		for (int i=0; i<m; i++) {
			for(int j=0; j<n; j++) {
				arr[i][j] = sc.nextInt();
				dp[i][j] = -1;
			}
		}

		// 위치 x,y
		fun(0, 0);
		System.out.println(dp[0][0]);

		for (int i=0; i<m; i++) {
			for(int j=0; j<n; j++) {
				System.out.print(dp[i][j] + " ");
			}
			System.out.println();
		}
	}

	static int[] nx = {1,-1,0,0};
	static int[] ny = {0,0,1,-1};
	public static int fun(int x, int y) {

		if (x == (m-1) && y == (n-1)) {
			return 1;
		}
		if (dp[x][y] > -1) {
			return dp[x][y];
		}

		int result = 0;
		for (int i=0; i<4; i++) {

			if(x+nx[i] < 0 || x+nx[i] >= m || y+ny[i] < 0 || y+ny[i] >=n)
				continue;
			if(arr[x+nx[i]][y+ny[i]] < arr[x][y])
				result += fun(x+nx[i], y+ny[i]);
		}

		return dp[x][y]=result;
	}

}


Reference