백준 10844번 쉬운 계단 수
1. 문제
https://www.acmicpc.net/problem/10844
어떤 수의 인접한 자리의 차이가 항상 1이면 이를 계단 수라고 한다.
문제는 다음과 같다.
길이가 N인 계단 수의 개수를 구하시오.
단 0으로 시작하는 수는 계단 수가 아니다.
2. 처음 떠올릴 수 있는 방법 (완전 탐색)
처음에는 이런 방식이 떠오를 수 있다.
1자리 숫자 만들기
→ 뒤에 숫자를 붙이기
→ 인접한 자리 차이가 1인지 확인
→ 뒤에 숫자를 붙이기
→ 인접한 자리 차이가 1인지 확인
예를 들어
1 → 10, 12
2 → 21, 23
3 → 32, 34
2 → 21, 23
3 → 32, 34
이런 식으로 계속 숫자를 만들어 나가는 방식이다.
하지만 이 방식은 문제가 있다.
길이가 최대 100이기 때문에 가능한 경우의 수가 거의 10^100수준이 된다.
즉 완전탐색은 불가능하다.
3. 핵심 아이디어 (DP)
숫자를 실제로 만들 필요는 없다.
우리가 알고 싶은 것은
"길이가 i일 때 마지막 숫자가 j인 계단 수의 개수"
그래서 다음과 같이 DP를 정의한다.
dp[i][j]는 길이가 i이고 마지막 숫자가 j인 계단 수의 개수
예를 들어 dp[3][4]의 의미는 길이가 3이고, 마지막 숫자가 4인 계단 수의 개수이다.
4. 점화식
계단 수의 특징은 인접한 자리 차이가 1이다.
즉 마지막 숫자가 j라면 이전 숫자는 j-1 또는 j+1뿐이다.
따라서 점화식은 dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]이다.
⚠️ 경계 처리
마지막 숫자가 0
이전 숫자는 1만 가능
dp[i][0] = dp[i-1][1]
마지막 숫자가 9
이전 숫자는 8만 가능
dp[i][9] = dp[i-1][8]
5. 초기값
길이가 1일 때 가능한 계단 수
1 2 3 4 5 6 7 8 9
따라서
dp[1][1] = 1
dp[1][2] = 1
...
dp[1][9] = 1
dp[1][2] = 1
...
dp[1][9] = 1
하지만
dp[1][0] = 0
왜냐하면 0으로 시작할 수 없기 때문이다.
6. DP 테이블
길이 1
| 개수 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
총 9
길이 2
| 개수 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 1 |
총 17
예시 출력과 동일하다.
7. 구현 코드 (Python)
import sys
input = sys.stdin.readline
n = int(input())
MOD = 1000000000
dp = [[0]*10 for _ in range(n+1)]
# 초기값
for i in range(1,10):
dp[1][i] = 1
# DP
for i in range(2,n+1):
dp[i][0] = dp[i-1][1]
dp[i][9] = dp[i-1][8]
for j in range(1,9):
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]
for j in range(10):
dp[i][j] %= MOD
print(sum(dp[n]) % MOD)
8. 시간 복잡도
DP 테이블 크기
100 × 10
따라서
O(N × 10)
즉 거의 O(N) 수준이다.
'코딩테스트' 카테고리의 다른 글
| [백준] 12865 - 평범한 배낭 (0) | 2026.03.18 |
|---|---|
| [백준] 9251 - LCS (0) | 2026.03.17 |
| [백준] 2565 - 전깃줄 (0) | 2026.03.16 |
| [백준] 1053번 - 가장 긴 증가하는 부분 수열 (0) | 2026.03.13 |
| [백준] 2156번 - 포도주 시식 (0) | 2026.03.12 |