N
: 자연수 ($ 1 ≤ N ≤ 100$)
길이가 N이면서 0~9 사이 모든 수가 등장하는 계단 수의 개수를 구하는 문제이다.
그 개수를 1,000,000,000으로 나눈 나머지를 출력해야 한다.
⭐️ 계단 수 조건
- 인접한 모든 자리의 차이가 1인 수
- 0으로 시작하는 수는 계단 수 ❌
‼️ 고려해야 할 점
위의 내용을 고려해 dp를 구현한다.
1️⃣ DP 테이블 만들기
dp[위치][숫자][비트마스크]
dp[1][1부터 9까지][비트마스크] = 1
로 초기화2️⃣ DP 테이블 채우기
x
사용 여부 표시 방법 : mask | (1 << x)
3️⃣ 결과 얻기
dp 테이블 채우기 →
최종 시간복잡도
N이 최대 100이므로 제한 시간 2초 내에 연산이 가능하다.
다이나믹 프로그래밍과 비트 마스킹 활용
import sys
input = sys.stdin.readline
# N 입력
N = int(input())
# dp 테이블 정의
dp = [[[0 for _ in range(1024)] for _ in range(10)] for _ in range(N+1)]
# dp 테이블 초기화
for i in range(1, 10):
dp[1][i][1 << i] = 1
# dp 테이븛 채우기
for n in range(2, N+1):
for i in range(10):
for bit in range(1024):
if i == 0:
dp[n][i][bit | (1 << i)] = (dp[n][i][bit | (1 << i)] + dp[n-1][i+1][bit]) % 1000000000
elif i == 9:
dp[n][i][bit | (1 << i)] = (dp[n][i][bit | (1 << i)] + dp[n-1][i-1][bit]) % 1000000000
else:
dp[n][i][bit | (1 << i)] = (dp[n][i][bit | (1 << i)] + dp[n-1][i+1][bit] + dp[n - 1][i - 1][bit]) % 1000000000
# 결과 계산
answer = sum(dp[N][j][1023] for j in range(10)) % 1000000000
# 결과 출력
print(answer)