백준 #10844 - 쉬운 계단 수
문제
45656이란 수를 보자.
이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.
입력
첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.
출력
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
예제 입력 1
1
예제 출력 1
9
예제 입력 2
2
예제 출력 2
17
전형적인 dp 문제였다.
먼저, dp 테이블을 만들어 주었다.
0 1 2 3 4 5 6 7 8 9
0
1
2
3
가로는 계단수를 구성할 0~9의 숫자를 나타내고,
세로는 계단수의 길이를 나타낸다.
계단수의 길이가 0인 경우는 없으니 건너뛰고, 계단수의 길이가 1인 경우부터 보자.
계단수의 길이가 1일 때는, 0을 제외한 1~9의 경우 모두 1개씩 존재하므로 dp[1]을 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1]로 초기화 한다.
0 1 2 3 4 5 6 7 8 9
0
1 0 1 1 1 1 1 1 1 1 1
2
3
계단수의 길이가 2일 때를 생각해보자.
1) 만일 마지막 숫자가 0이라면, 그 전 숫자는 1만 올 수 있다.
2) 만일 마지막 숫자가 9라면, 그 전 숫자는 8만 올 수 있다.
3) 만일 마지막 숫자가 1~8이라면, 그 전 숫자는 (마지막 숫자 - 1), (마지막 숫자 + 1)의 2개이다.
이를 점화식으로 표현해보자.
1) 만일 마지막 숫자가 0이라면 --> dp[i][j] = dp[i - 1][1]
2) 만일 마지막 숫자가 9라면 --> dp[i][j] = dp[i - 1][8]
3) 만일 마지막 숫자가 1~8이라면 --> dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1]
그럼 다음과 같은 식을 작성할 수 있다.
dp[1]은 초기화 한 상태이기에 i = 2부터 돌면 된다
# 1 2 3 4 5 6 7 8 9
import sys
input = sys.stdin.readline
n = int(input())
dp = [[0] * 10 for _ in range(n + 1)]
dp[1] = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
for i in range(2, n + 1):
for j in range(10):
if j == 0:
dp[i][j] = dp[i - 1][1]
elif j == 9:
dp[i][j] = dp[i - 1][8]
else:
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j + 1]
answer = sum(dp[n])
print(answer % 1000000000)