Post

BOJ_1562_계단수(Java)

BOJ_1562_계단수(Java)

[Gold I] 계단 수 - 1562

문제 링크

성능 요약

메모리: 19936 KB, 시간: 144 ms

분류

비트마스킹, 다이나믹 프로그래밍, 비트필드를 이용한 다이나믹 프로그래밍

제출 일자

2024년 9월 2일 15:34:15

문제 설명

45656이란 수를 보자.

이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.

N이 주어질 때, 길이가 N이면서 0부터 9까지 숫자가 모두 등장하는 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. 0으로 시작하는 수는 계단수가 아니다.

입력

첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.

출력

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

문제 풀이

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 * Author : nowalex322, Kim Hyeonjae
 */

import java.io.*;
import java.util.*;

public class Main {
	static BufferedReader br;
	static final long MOD = (long) 1e9;

	public static void main(String[] args) throws IOException {
//		br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
		br = new BufferedReader(new InputStreamReader(System.in));
		int len = Integer.parseInt(br.readLine());

		/**
		 * dp에 필요한 저장값 : 끝 숫자, 길이, 방문처리 비트마스킹
		 */
		int dp[][][] = new int[10][len + 1][1 << 10];

		for (int i = 0; i <= 9; i++) {
			dp[i][1][1 << i] = 1;
		}

		// 우선순위 : 숫자 길이 -> 숫자 -> 방문처리 체크		
		for (int j = 2; j <= len; j++) {
			for (int i = 0; i <= 9; i++) {
				for (int k = 0; k < (1 << 10); k++) {
					int visited = k | (1 << i);
					
					if (i == 0) dp[i][j][visited] += dp[1][j - 1][k] % MOD;
					else if (i == 9) dp[i][j][visited] += dp[8][j - 1][k] % MOD;
					else dp[i][j][visited] += (dp[i - 1][j - 1][k] % MOD + dp[i + 1][j - 1][k] % MOD);
					
					dp[i][j][visited] %= MOD;
				}
			}
		}
		
		long ans = 0;
		for (int i = 1; i <= 9; i++) {
			ans += dp[i][len][(1 << 10) - 1];// 여기 %MOD넣으면 1e9넘는 값 더할때 이상하게 더해져서 long으로 큰 값 더해놓고 마무리로 나머지 구하기
		}
		System.out.println(ans % MOD);
	}
}
This post is licensed under CC BY 4.0 by the author.