백준 10844번 (쉬운 계단 수, C++, DP) [BAEKJOON]

쉬운 계단 수

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

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초256 MB116877369762670229.843%

문제

45656이란 수를 보자.

이 수는 인접한 모든 자리의 차이가 1이다.

이런 수를 계단 수라고 한다.

N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자.

0으로 시작하는 수는 계단수가 아니다.

입력

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

출력

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

예제 입력 1

1

예제 출력 1

9

예제 입력 2

2

예제 출력 2

17

예제 입력 A

100

예제 출력 A

18404112

예제 입력 B

70

예제 출력 B

564706557

출처

알고리즘 분류


접근하는 방법

N = 1 => 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 (0으로 시작하는 수는 계단수가 아니다.)

N = 2 => 10 / 12 / 21 / 23 / 32 / 34 / 43 / 45 / 54 / 56 / 65 / 67 / 76 / 78 / 87 / 89 / 98

N = 3 => 101 / 121 / 123 / 210 / 212 / 321 / 324 ….

N = 2 일 경우를 예시로 들어보면

마지막 숫자 전 수가 2인 경우 마지막 숫자에 올 수 있는 수는 1, 3 – 2가지의 경우 / 21, 23

마지막 숫자 전 수가 3인 경우 마지막 숫자에 올 수 있는 수는 2, 4 – 2가지의 경우 / 32, 34

마지막 숫자가 0 이라면 1가지의 경우 / 10

마지막 숫자가 9 라면 1가지의 경우 / 89

위의 내용을 표로 정리하면 아래와 같이 나온다.

 N의 범위는 1<= N <= 100

구하는 값은 계단 수의 개수를 1,000,000,000으로 나눈 나머지를 출력하는 것

통과된 코드

#include <iostream>

using namespace std;

constexpr int MOD = 1000000000;

int N;

// dp[i][j] 
// i = 숫자, j = 자릿수
long long dp[10][101];

// DP 초기화
void DP_Initialization()
{
	dp[0][1] = 0;
	for (int i = 1; i < 10; i++) {
		dp[i][1] = 1;
	}
}

int main()
{
	cin >> N;

	long long result = 0;

	DP_Initialization();

	for (int j = 2; j <= N; j++) {
		for (int i = 0; i < 10; i++) {
			if (i == 0) { // 마지막 숫자가 0
				dp[i][j] = dp[1][j-1]; 
			}
			else if (i == 9) { // 마지막 숫자가 9
				dp[i][j] = dp[8][j-1];
			}
			else {
				// 모듈러 연산 덧셈
				dp[i][j] = ( (dp[i-1][j-1] % MOD) + ( dp[i + 1][j - 1] % MOD) ) % MOD;
			}
		}
	}

	for (int i = 0; i < 10; i++) {
		result += ( dp[i][N] % MOD ); // 모듈러 연산 덧셈
	}

	cout << result % MOD; // 모듈러 연산 덧셈

	return 0;
}

DP 문제는 점화식을 만들기가 너무 어려운 것 같다.


문제가 이해하기 어렵다면 아래의 영상을 시청하는 것을 추천

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다