https://www.acmicpc.net/problem/1562
- 현재 자리수
- 현재까지 0~9까지 숫자의 방문 여부
- 마지막 수
DP[현재 자리수][0~9방문여부(비트마스킹)][마지막 수]
DP[ind][chk][last] =
DP[ind-1][chk][last+1] + --------------> 마지막수 + 1
DP[ind-1][chk - (2<<last)][last+1] + ---> 마지막수 + 1, chk에서 마지막수 없앰
DP[ind-1][chk][last-1] + ---------------> 마지막수 - 1
DP[ind-1][chk - (2<<last)][last=1] + ---> 마지막수 - 1, chk에서 마지막수 없앰
import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader br;
public static BufferedWriter bw;
public static int N, MOD = 1000000000, INF = 987654321;
public static int[][][] dp;
public static int dfs(int ind, int chk, int last) {
//기저조건1 : 첫째자리인 경우
if (ind == 1) {
if (last != 0 && chk == (1<<last)) return 1;
else return 0;
}
//기저조건2 : 방문 체크에 마지막 수가 포함되지 않은 경우
if ((chk & (1<<last)) != (1<<last)) return 0;
//기저조건3 : 메모이제이션이 된 경우
if (dp[ind][chk][last] != INF) return dp[ind][chk][last];
int result = 0;
if (last + 1 != 10) {
result = (result + dfs(ind-1, chk, last + 1)) % MOD;
result = (result + dfs(ind-1, chk - (1<<last), last + 1)) % MOD;
}
if (last - 1 != -1) {
result = (result + dfs(ind-1, chk, last - 1)) % MOD;
result = (result + dfs(ind-1, chk - (1<<last), last - 1)) % MOD;
}
return dp[ind][chk][last] = result;
}
public static void input() throws IOException {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
dp = new int[N+1][1<<10][10];
for (int a = 0; a < N+1; a++) {
for (int b = 0; b < (1<<10); b++) {
for (int c =0; c < 10; c++)
dp[a][b][c] = INF;
}
}
}
public static void solve() throws IOException {
int result = 0;
for (int i = 0; i < 10; i++)
//0~9 모두 방문한 케이스만 계산함
result = (result + dfs(N, (1<<10) - 1, i)) % MOD;
bw.write(result + "\n");
bw.flush();
}
public static void main(String[] args) throws IOException {
input();
solve();
}
}