[백준] 10844 쉬운 계단 수

Python
avatar
2025.03.19
·
5 min read

문제

45656이란 수를 보자.
이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.


입력

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


출력

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


내 풀이

n = int(input())

# dp[i][j] : 길이가 i이고 마지막 숫자가 j인 계단 수의 개수
dp = [[0]*10 for _ in range(n+1)]

for j in range(1, 10):    # N = 1일 때 1~9 초기화
    dp[1][j] = 1

for i in range(2, n+1):
    for j in range(10):
        if j == 0:     # 끝자리가 0이면 1밖에 붙일 수 없음
            dp[i][j] = dp[i-1][1]
        elif j == 9:  # 끝자리가 9이면 8밖에 붙일 수 없음  
            dp[i][j] = dp[i-1][8]
        else:   # 그 외에는 j-1, j+1의 수를 붙일 수 있음
            dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1])%1000000000  
            
print(sum(dp[n])%1000000000)
  • 시간 복잡도 → O(N)O(N)
    이중 for문이지만 내부 반복문은 10번씩만 반복됨

  • 공간 복잡도 → O(N)O(N)
    2차원 배열이지만 n개의 요소를 가지고 각 요소는 10개의 요소만을 가짐


코멘트

계단 수를 구할 때 아래의 표와 같이 생각하면 좀 수월하다. 아래 표와 같이 계단 수를 만들다 보면 N = i → N = i+1 로 갈 때의 규칙을 찾을 수 있다.
(1) 0으로 끝나는 수는 뒤에 1밖에 붙일 수 없다.
ex) 10 → 101
(2) 9로 끝나는 수는 뒤에 8밖에 붙일 수 없다.
ex) 89 → 898
(3) 그 외의 수는 1 작은 수, 1 큰 수를 붙일 수 있다.
ex) 43 → 432, 434

N = 1

N = 2

N = 3

1로 시작

1

10, 12

101, 121, 123

2로 시작

2

21, 23

210, 212, 232, 234

3으로 시작

3

32, 34

321, 323, 343, 345

4로 시작

4

43, 45

432, 434, 454, 456

5로 시작

5

54, 56

543, 545, 565, 567

6으로 시작

6

65, 67

654, 656, 676, 678

7로 시작

7

76, 78

765, 767, 787, 789

8로 시작

8

87, 89

876, 878, 898

9로 시작

9

98

987, 989

이런 규칙을 찾기도 어려웠는데 dp 배열을 구현하는 것은 더 어려웠다. 2차원 dp 배열을 이용하는 식이었다. dp[i][j] : 길이가 N = i이고 마지막 숫자가 j인 계단 수의 개수로 정의를 하고 길이가 1인 계단 수를 초기화해둔다. 그리고 위에서 찾은 규칙을 코드로 구현하면 된다.


References

https://www.acmicpc.net/problem/10844







- 컬렉션 아티클