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));
'코딩 테스트 > 백준' 카테고리의 다른 글
1339 단어 수학 (자바스크립트) (0) | 2025.01.08 |
---|---|
11057 오르막 수 (자바스크립트) (0) | 2025.01.08 |
1699 제곱수의 합 (0) | 2025.01.08 |
15990 1,2,3 더하기 5 (0) | 2025.01.08 |
11052 카드 구매하기, 16194 카드 구매하기 2 (0) | 2025.01.08 |