최대
N x M
범위가 작아 DFS로 모든 경로를 탐색해도 시간 초과는 발생하지 않지만 DP배열을 사용한 반복문으로 효율적으로 해결할 수 있다.
1. 입력
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int ox = -1, oy = -1;
if (k != 0) {
ox = (k - 1) / m;
oy = (k - 1) % m;
}
N
과 M
, 그리고 O
가 표시된 칸의 좌표 위치를 구한다.2. DP 배열 초기화
//(x, y, 0) = (x, y) 위치에 O로 표시된 칸을 지나지 않은 경로 수
//(x, y, 1) = (x, y) 위치에 O로 표시된 칸을 지나간 경로 수
int[][][] dp = new int[n][m][2];
dp[0][0][0] = 1;
O
로 표시된 칸을 지난 경우와 지나지 않은 경우를 관리한다.3. 반복문으로 DP 배열 값 채우기
int[][] dir = {{1, 0}, {0, 1}};
for (int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
//오른쪽 또는 아래로 이동
for (int[] d : dir) {
int nx = x + d[0];
int ny = y + d[1];
if (nx >= n || ny >= m) continue;
//다음 칸이 O로 표시된 칸인 경우
if (nx == ox && ny == oy) {
dp[nx][ny][1] += dp[x][y][0];
} else {
dp[nx][ny][0] += dp[x][y][0];
dp[nx][ny][1] += dp[x][y][1];
}
}
}
}
O
로 표시된 칸이라면, 전까지 O
를 지나지 않은 경로를 더해준다. (전이시킨다.)4. 결과 출력
System.out.println(dp[n - 1][m - 1][(k == 0) ? 0 : 1]);
k == 0
이면 O
를 지나지 않은 경로 수를 출력하고, 아니면 O
를 지난 경로 수를 출력한다.O(N x M)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BJ_10164 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int ox = -1, oy = -1;
if (k != 0) {
ox = (k - 1) / m;
oy = (k - 1) % m;
}
//(x, y, 0) = (x, y) 위치에 O로 표시된 칸을 지나지 않은 경로 수
//(x, y, 1) = (x, y) 위치에 O로 표시된 칸을 지나간 경로 수
int[][][] dp = new int[n][m][2];
dp[0][0][0] = 1;
int[][] dir = {{1, 0}, {0, 1}};
for (int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
//오른쪽 또는 아래로 이동
for (int[] d : dir) {
int nx = x + d[0];
int ny = y + d[1];
if (nx >= n || ny >= m) continue;
//다음 칸이 O로 표시된 칸인 경우
if (nx == ox && ny == oy) {
dp[nx][ny][1] += dp[x][y][0];
} else {
dp[nx][ny][0] += dp[x][y][0];
dp[nx][ny][1] += dp[x][y][1];
}
}
}
}
System.out.println(dp[n - 1][m - 1][(k == 0) ? 0 : 1]);
}
}
n, m, k = map(int, input().split())
ox, oy = -1, -1
if k != 0:
ox, oy = divmod(k - 1, m)
dp = [[[0, 0] for _ in range(m)] for _ in range(n)]
dp[0][0][0] = 1
for x in range(n):
for y in range(m):
for dx, dy in [(1, 0), (0, 1)]:
nx = x + dx
ny = y + dy
if nx >= n or ny >= m:
continue
if (nx, ny) == (ox, oy):
dp[nx][ny][1] += dp[x][y][0]
else:
dp[nx][ny][0] += dp[x][y][0]
dp[nx][ny][1] += dp[x][y][1]
print(dp[n - 1][m - 1][0 if k == 0 else 1])