본문 바로가기
코딩 테스트/백준

10844 쉬운 계단 수 (자바스크립트)

by 위그든씨 2025. 1. 8.

45656이란 수를 보자.

이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.

N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.

입력

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

출력

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

====

문제 분석

자릿수를 row로 두고 각 자릿수를 만들 때 마지막 숫자로 올 수 있는 0~9를 col로 둔 뒤 

각 자릿수의 숫자 조합을 만들 때 마지막으로 오는 숫자의 횟수를 dp[row][col]에 기록해두는 문제이다.

만약 세 자리수를 만든다면 이는 두 자리수 중 마지막에 1을 쓴 경우의 수에 0 또는 2를 추가하면 된다.

이를 점화식으로 표현하면 아래와 같이 나온다.

dp[num][digit] = (dp[num - 1][digit - 1] + dp[num - 1][digit + 1]) % INF;

단, 현재 자리수를 구성할 때 마지막에 0이 올 수 있는 경우는 이전 자리수 중 1이 마지막으로 왔을 떄만 가능하다.

dp[num][0] = dp[num - 1][1] % INF;

이는 마지막에 9가 오는 경우도 이전 자리수 중 끝에가 8일때만 가능하므로

dp[num][9] = dp[num - 1][8] % INF;

전체 점화식 코드는 

for (let num = 2; num <= MAX; num++) {
    dp[num][0] = dp[num - 1][1] % INF;
    for (let digit = 1; digit < 9; digit++) {
        dp[num][digit] =
            (dp[num - 1][digit - 1] + dp[num - 1][digit + 1]) % INF;
    }
    dp[num][9] = dp[num - 1][8] % INF;
}

정답 코드

const input = require('fs')
    .readFileSync(process.platform === 'linux' ? '/dev/stdin' : './input.txt')
    .toString()
    .trim()
    .split('\n');

const MAX = 100;
const INF = 1_000_000_000;
const n = +input[0];
const dp = Array.from({ length: MAX + 1 }, () =>
    Array.from({ length: 10 }, () => 0)
);
for (let i = 1; i < 10; i++) {
    dp[1][i] = 1;
}
for (let num = 2; num <= MAX; num++) {
    dp[num][0] = dp[num - 1][1] % INF;
    for (let digit = 1; digit < 9; digit++) {
        dp[num][digit] =
            (dp[num - 1][digit - 1] + dp[num - 1][digit + 1]) % INF;
    }
    dp[num][9] = dp[num - 1][8] % INF;
}

console.log(dp[n].reduce((acc, cur) => (acc + cur) % INF, 0));