ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 - 파이프 옮기기 1 (17070) [C++]
    문제 풀이/백준 2024. 4. 8. 14:18
    반응형

    이 문제는 다이나믹 프로그래밍을 이용해서 풀었다.

     

    입력 배열의 최대 크기가 16 x 16으로 작긴 하다. 그러나 혹시 모를 시간 초과를 대비하여 다이나믹 프로그래밍으로 확실하게 시간을 줄였다.

     

    dp[y][x][direction] : (y, x) 위치에서 direction으로 파이프가 놓여져 있을 때 이동시킬 수 있는 경우의 수

    로 놓아서 문제를 쉽게 해결할 수 있었다.

    #include <iostream>
    #include <vector>
    #include <utility>
    #include <queue>
    using namespace std;
    
    #define MAX 16
    #define GARO 0
    #define DAEGAK 1
    #define SERO 2
    
    int N;
    int house[MAX + 1][MAX + 1];
    int dp[MAX + 1][MAX + 1][3];
    
    void init() {
    	for (int y = 1; y <= N; y++) {
    		for (int x = 1; x <= N; x++) {
    			for (int i = 0; i < 3; i++) {
    				dp[y][x][i] = -1;
    			}
    		}
    	}
    }
    
    void input() {
    	cin >> N;
    	for (int y = 1; y <= N; y++) {
    		for (int x = 1; x <= N; x++) {
    			cin >> house[y][x];
    		}
    	}
    }
    
    bool inRange(int y, int x) {
    	if (1 <= y && y <= N && 1 <= x && x <= N) {
    		return true;
    	}
    	return false;
    }
    
    int solve(int y, int x, int direction) {
    	if (y == N && x == N) {
    		return 1;
    	}
    	if (dp[y][x][direction] != -1) {
    		return dp[y][x][direction];
    	}
    	int result = 0;
    	if (direction == GARO) {
    		// garo
    		if (inRange(y, x + 1) && house[y][x + 1] == 0) {
    			result += solve(y, x + 1, GARO);
    		}
    		// daegak
    		if (inRange(y, x + 1) && inRange(y + 1, x + 1) && inRange(y + 1, x)) {
    			if (house[y][x + 1] == 0 && house[y + 1][x + 1] == 0 && house[y + 1][x] == 0) {
    				result += solve(y + 1, x + 1, DAEGAK);
    			}
    		}
    		return dp[y][x][direction] = result;
    	} else if (direction == SERO) {
    		// sero
    		if (inRange(y + 1, x) && house[y + 1][x] == 0) {
    			result += solve(y + 1, x, SERO);
    		}
    		// daegak
    		if (inRange(y, x + 1) && inRange(y + 1, x + 1) && inRange(y + 1, x)) {
    			if (house[y][x + 1] == 0 && house[y + 1][x + 1] == 0 && house[y + 1][x] == 0) {
    				result += solve(y + 1, x + 1, DAEGAK);
    			}
    		}
    		return dp[y][x][direction] = result;
    	} else {
    		// garo
    		if (inRange(y, x + 1) && house[y][x + 1] == 0) {
    			result += solve(y, x + 1, GARO);
    		}
    		// daegak
    		if (inRange(y, x + 1) && inRange(y + 1, x + 1) && inRange(y + 1, x)) {
    			if (house[y][x + 1] == 0 && house[y + 1][x + 1] == 0 && house[y + 1][x] == 0) {
    				result += solve(y + 1, x + 1, DAEGAK);
    			}
    		}
    		// sero
    		if (inRange(y + 1, x) && house[y + 1][x] == 0) {
    			result += solve(y + 1, x, SERO);
    		}
    		return dp[y][x][direction] = result;
    	}
    }
    
    int main() {
    	ios_base::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    
    	input();
    	init();
    	cout << solve(1, 2, GARO) << '\n';
    
    	return 0;
    }
    반응형
Designed by Tistory.