728x90
https://www.acmicpc.net/problem/17069
17069번: 파이프 옮기기 2
유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의
www.acmicpc.net
파이프를 가로 세로 대각선으로만 이동할 수 있고, 회전할때 45도로만 회전할수 있다.
그러므로 가로로 갈수 있는 방법은 가로 => 가로 대각선 =>가로이고,
세로로 갈수 있는 방법은 세로 =. 세로, 대각선 => 세로이며,
대각선으로 갈수 잇는 방법은 가로 => 대각선, 세로 => 대각선, 대각선 => 대각선이다.
(물론 중간에 장애물이 있으면 안된다.)
dp[dir][i][j] 가 i,j 에서 dir 방향으로 갈수 있는 경우수라고 하면(dir : 0 가로 dir : 1대각선 dir : 2 세로 라고 하먄)
다음과 같은 점화식이 만들어진다.
이 dp 점화식을 i= 0 ~N j = 0~ N 까지 모두 돌려준뒤
마지막 점인 N-1, N-1에서 dp배열의 총 합만 구해주면된다.
이 알고리즘의 시간 복잡도는 O(N^2), 공간 복잡도는 O(N^2)이다.
if(j+1< N && map[i][j+1] == 0 ) {//장애물 체크
dp[0][i][j+1] += dp[0][i][j]; //가로 => 가로
dp[0][i][j+1] += dp[1][i][j]; //대각선 => 가로
}
if(j+1<N && i+1 <N && map[i+1][j]==0 && map[i+1][j+1]==0 && map[i][j+1] ==0) {
dp[1][i+1][j+1] += dp[0][i][j]; //가로 => 대각선
dp[1][i+1][j+1] += dp[2][i][j]; //세로 => 대각선
dp[1][i+1][j+1] += dp[1][i][j]; //대각선 => 대각선
} //대각선 이동
if(i+1<N && map[i+1][j]==0) {
dp[2][i+1][j] += dp[2][i][j]; //세로 => 세로
dp[2][i+1][j] += dp[1][i][j];//대각선 => 세로
}//세로 이동
package 백준;
import java.util.*;
import java.io.*;
public class 파이프옮기기2 {
static class MyScanner{
BufferedReader bf;
StringTokenizer st;
MyScanner(){
bf = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while(st==null||!st.hasMoreTokens()) {
try {
st = new StringTokenizer(bf.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyScanner sc = new MyScanner();
int N = sc.nextInt();
int map[][] = new int[N][N];
long dp[][][] = new long[3][N][N];
for(int i =0 ;i <N;i++) {
for(int j=0 ; j <N;j++) {
map[i][j] = sc.nextInt();
}
}
dp[0][0][1] = 1; //0 가로 1 대각선 2 세로
for(int i =0 ;i < N;i++) {
for(int j= 0;j<N;j++) {
if(j+1< N && map[i][j+1] == 0 ) {//가로로 한칸이동
dp[0][i][j+1] += dp[0][i][j];
dp[0][i][j+1] += dp[1][i][j];
}
if(j+1<N && i+1 <N && map[i+1][j]==0 && map[i+1][j+1]==0 && map[i][j+1] ==0) {
dp[1][i+1][j+1] += dp[0][i][j];
dp[1][i+1][j+1] += dp[2][i][j];
dp[1][i+1][j+1] += dp[1][i][j];
} //대각선 이동
if(i+1<N && map[i+1][j]==0) {
dp[2][i+1][j] += dp[2][i][j];
dp[2][i+1][j] += dp[1][i][j];
}//세로 이동
}
}
long answer = 0;
for(int i =0 ;i <3;i++) {
answer+=dp[i][N-1][N-1];
}
System.out.println(answer);
}
}