ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ) 계단 수 (1562 번)
    알고리즘/백준 2021. 3. 7. 17:19
    반응형

    계단 수

     

    1562번: 계단 수

    첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.

    www.acmicpc.net

    45656, 1210123 과 같이 각 자릿 수의 차이가 1씩 나는 수를 계단 수라고 한다.

     

    자릿 수를 의미하는 n이 주어질 때, 이러한 계단수가 몇 개 존재하는지 구하는 문제다.

    이 때, 모든 계단 수는 0으로 시작하지 않는다.

     

    DP와 비트 마스크를 활용해서 푸는 문제로, 각 자릿수, 0 ~9의 수, 비트마스크를 저장할 3차원 정수형 배열 DP를 이용해서 풀었다.

    우선, n = 1인 경우, 0 ~ 9는 각각 자신 수 하나를 가진다.

    이를 비트마스크로 표현해주면서, n을 증가시켰다.

     

    0인 경우에는 0으로 시작할 수 없기 때문에, 0다음에 올 수 있는 수인 1만 dp에 추가시켜주었다.

    이외에 1 ~ 8은 각각 앞뒤로 숫자를 추가시켜 계단 수를 만들 수 있기 때문에, 다음 인덱스의 숫자도 함께 체크하면서 dp에 저장했다.

    여기서, 9를 따로 체크해주지 않고 배열의 공간을 11로 잡아주어 out of index를 따로 체크하지 않았다.

     

    이렇게 저장된 dp의 n 자릿 수에서, 0 ~ 9 까지의 공간을 탐색하며 값을 더해준다.이 때, 모든 숫자 0 ~ 9가 저장된 경우를 찾아야하기 때문에, 모두 저장되어 있는 비트마스크 (1 << 10) -1 번 째 인덱스를 탐색하며 답을 구해준다.

     

    또한, 문제의 조건에 1,000,000,000으로 나눈 나머지를 출력하는 조건이 있기 때문에, DP를 저장할 때와 값을 구할 때 모두 MOD를 해주었다.

     

     

    코드

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    
    public class StairNumber_1562 {
      public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
    
        br.close();
        solution(n);
      }
    
      private static void solution(int n) {
        final int MAX_NUMBER =9, MOD = 1000000000, ALL_VISIT = (1<<10) -1; // 0 ~ 10 비트마스크
        int[][][] dp = new int[n+1][MAX_NUMBER+2][ALL_VISIT+1];
        for(int i=1; i<=MAX_NUMBER; i++) {
          dp[1][i][1 << i] = 1;
        }
    
        for(int i=2; i<=n; i++) {
          for(int j=0; j<=MAX_NUMBER; j++) {
            for(int k=0; k<=ALL_VISIT; k++) {
              dp[i][j][k | 1 << j] = (dp[i][j][k | 1 << j] + dp[i-1][j+1][k]) % MOD;
              if(j !=0) { // 0인 경우 out of index 방지
                dp[i][j][k | (1 << j)] = (dp[i][j][k | (1 << j)] + dp[i - 1][j - 1][k]) % MOD;
              }
            }
          }
        }
    
        int answer =0;
        for(int i=0; i<=MAX_NUMBER; i++) {
          answer = (answer + dp[n][i][ALL_VISIT]) % MOD;
        }
        System.out.println(answer);
      }
    }
    
    반응형

    '알고리즘 > 백준' 카테고리의 다른 글

    BOJ) 카드 게임  (0) 2021.03.07
    BOJ) 사회망 서비스(SNS) (2533 번)  (0) 2021.03.03
    BOJ) 작업 (2056 번)  (0) 2021.03.03
    BOJ) 빵집 (3109 번)  (0) 2021.02.23
    BOJ) 자두나무 (2240 번)  (0) 2021.02.23

    댓글

Designed by Tistory.