ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2186 문자판
    백준/DP 다이나믹 프로그래밍 2024. 8. 27. 22:18

     

     

     

    dp 와 dfs 를 이용한다.

     

    거꾸로 찾아나가는 방식이다.

    BREAK 이 문자를 찾아나가야 할 때,

     

    dp[1][2][3] = 위치(1,2) 에서 시작된 문자로 

    BREAK 문자열의 3번째 부터 끝 문자열까지 완성할 수 있는 경우의 수이다.

    즉, AK 를 완성할 수 있는 경우의 수로,

     

    KAKT
    XEAS
    YRWU
    ZBQP

     

    위치 (1,2) 의 문자열 = A인데,

    여기에서 좌,우,위, 아래로 움직여서 K가 있는 경우를 찾아보면 한 가지 경우를 찾을 수 있다.

    때문에 dp[1][2][3] = 1 이다.

     

     

     

    (1) 코드 설명 

     

    KAKT
    XEAS
    YRWU
    ZBQP

     

    1) 

    BREAK에서 맨 처음 문자 B가 있는 위치(3,1)에서 dfs가 시작한다.

     

     

    ===============================

     

    KAKT
    XEAS
    YRWU
    ZBQP

     

    2) 

    (3,1)의 위치에서 좌,우,위,아래 방향으로 다음 글자인

    R이 있는 위치 (2,1) 에서 또 dfs가 진행된다.

     

     

    ====================================

     

     

     

     

    KAKT
    XEAS
    YRWU
    ZBQP

     

     

    3) 

    (2,1)의 위치에서 좌,우,위,아래 방향으로 다음 글자인

    E가 있는 위치 (1,1) 에서 또 dfs가 진행된다.

     

     

    =======================================

     

     

    4) 

    KAKT
    XEAS
    YRWU
    ZBQP

     

    (1,1)의 위치에서 좌,우,위,아래 방향으로 다음 글자인

    A가 있는 위치 (0,1) 에서 또 dfs가 진행된다.

     

    ============================================

     

    5) 

    KAKT
    XEAS
    YRWU
    ZBQP

     

    (0,1)의 위치에서 좌,우,위,아래 방향으로 다음 글자인

    K가 있는 위치 (0,2) 에서 또 dfs가 진행된다.

     

     

    ==========================================

     

    그런데 이제 마지막 글자이므로 

    이 경우는 값 1을 리턴한다.

    그래서 dp[0][2][4] = 1 이다. 

    즉 위치 (0,2) 에서 A를 만들 수 있는 경우의 수가 1이다.

     

    그러면 dp[0][1][3] 에는 1이 더해지게 된다. 

    즉, 위치 (0,1) 에서 AK를 만들 수 있는 경우가 1만큼 증가함.

     

     

     

    이런 식으로 아래에서부터 위로 올라가는 형식으로 해결하면 된다. 

     

     

     

     

    맨 처음 dp 배열을 모두 -1 로 채운 이유는 방문하지 않았음을 표현하는 것이다.

     

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.StringTokenizer;
    
    
    public class Main {
    	
    	static char[][] board;
    	static int dp[][][];
    	static int N;
    	static int M;
    	static int K;
    	static String word;
    	
        public static void main(String[] args)  throws IOException {  
        	
        	  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
              StringTokenizer st = new StringTokenizer(br.readLine(), " ");
              N = Integer.parseInt(st.nextToken());
              M = Integer.parseInt(st.nextToken());
              K = Integer.parseInt(st.nextToken());
              board = new char[N][M];
    	
    		  for (int i = 0; i < N; i++) {
    		          String input = br.readLine();
    		         
    		          for (int j = 0; j < M; j++) {
    		              board[i][j] = input.charAt(j);
    		          }
    		      }	  
    		  
    		  	word = br.readLine();
    			
    			   dp = new int[N][M][word.length()];
    			   for (int i = 0; i < N; i++) {
    		              for (int j = 0; j < M; j++) {
    		                  Arrays.fill(dp[i][j], -1);
    		              }
    		          }
    			  long count = 0;
    			  for(int i=0; i<N; i++) {
    				  for(int j =0; j<M; j++) {
    					  
    					  if(board[i][j] == word.charAt(0)){
    					
    						  count+=dfs(i,j,0);						  
    					  }						  
    			  }
        }
        
      System.out.println(count);
         
    }
        
    
        public static int dfs(int x, int y, int length) {
    	
        	
        	if(dp[x][y][length]!=-1) {    	
        		return dp[x][y][length];
        		
        	}
       
        	if(length == (word.length()-1)) {    	
        		return dp[x][y][length]=1;
        		
        	}
        	
        	dp[x][y][length] = 0;
        	
        	int dx[] = {-1,1,0,0};
        	int dy[] = {0,0,-1,1};
    	
        	for(int i=1; i<=K; i++) {
    	    	for(int j=0; j<4; j++) {
    	    		
    	    		int nextX = x + dx[j]*i;
    	    		int nextY = y + dy[j]*i;	    		
    	    		
    	    		if(nextX>=0 && nextX<N && nextY>=0 && nextY<M) {
    	    		
    	    			if (board[nextX][nextY] == word.charAt(length+1)){
    	    				
    	    				dp[x][y][length] += dfs(nextX, nextY,length+1);    				
    	    			}    			
    	    		}
    	    	}
        }
        	
        	
        	return dp[x][y][length];
      }
    }

     

     

    참고 블로그 : [알고리즘/백준] 2186번: 문자판 (JAVA) (velog.io)

     

    [알고리즘/백준] 2186번: 문자판 (JAVA)

    백준 2186번: 문자판 문제 입출력 문제 접근법 문제를 읽어보고 미로 찾기와 비슷한 유형의 문제라고 생각하며 풀이를 진행했다. 처음 문제를 풀며 신경 쓴 부분은 다음과 같다. 방향 배열 dx, dy를

    velog.io

     

    '백준 > DP 다이나믹 프로그래밍' 카테고리의 다른 글

    1135 뉴스 전하기  (0) 2024.08.23
    2156 포도주 시식  (0) 2024.08.09
    10844 쉬운 계단 수  (0) 2024.08.07
    1788 피보나치 수의 확장  (0) 2024.07.09
    1915 가장 큰 정사각형  (0) 2024.06.26

    댓글

Designed by Tistory.