45656이란 수를 보자.
이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.
첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
import sys
sys.stdin = open("input.text", "rt")
n = int(input())
#인접한 수
dp = [[0] * 101 for _ in range(n+1)]
dp[1][0] = 0
for i in range(1,10):
dp[1][i] = 1
#자명한건 미리 초기화
for i in range(2,n+1):
dp[i][0] = dp[i-1][1] #0이 맨 뒤에 오려면 무조건 앞에 1이 있어야.
dp[i][9] = dp[i-1][8] #9가 맨 뒤에 오려면 무조건 앞에 8이 있어야.
for j in range(1,9): #1~8은 양쪽 대각선 모두 존재하니깐
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]
res = sum(dp[n][:10]) #길이가 n이니까 n번째 자리수의 0으로 끝나는거부터 9로 끝나는거까지 총 가짓수 더하면 돼
print(res % 1000000000)
이 문제는 조건을 잘 파악해야 한다.
⚽ 각 자리수에서 맨 뒤에 올 수 있는 숫자가 무엇인지에 대해서 생각하자.
n=1 → n=2로 바뀔 때 이제 이 때를 잘 파악했어야 했다.
dp[i][j]는 자릿수가 i인데 j라는 숫자가 앞에올 때의 경우의 수이다.
앞에 오는 숫자가 무엇인지에 따라서 바뀌는 것이었다 !
앞에 오는 숫자 = 0
dp[자리수][0] = dp[자리수-1][1]
0은 무조건 1뒤에 와야하니깐 값이 변하지 않음.
앞에 오는 숫자 = 1~8
dp[자리수][j] = dp[자리수-1][j-1] + dp[자리수-1][j+1]
앞에 오는 숫자 = 9
dp[자리수][9] = dp[자리수-1][8]
9 역시 무조건 8뒤에 나와야함.
이 규칙을 찾아보면 해당 위치의 대각선 위 위치의 숫자들의 합인걸 알 수 있다.
이렇게 점화식을 세워 코드를 작성하면 된다.
i = 자릿수
j = 맨 뒤에 갈 수 있는 경우의 수
즉 dp[i][j]는 i번째 자리수의 맨 뒤에 j라는 숫자가 올 때의 경우의 수 누적.
⚽ dp문제를 풀다 보니까 마지막 항에 대해서 어떻게 될까? 를 고민하는 것이 어느정도 있어야 할 것 같다.