메모리: 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으로 나눈 나머지를 출력한다.
문제 풀이

/**
* 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);
}
}