(C++) 백준 10844번 - 쉬운 계단 수

코딩너구리·2025년 11월 24일

코딩 문제 풀이

목록 보기
100/266

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

문제

> 45656이란 수를 보자.
> 이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
> N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.

접근

dp를 이차원 벡터로 선언해 자릿수, 올 수있는 수의 조합으로 만든다.
예를 들어 N이 4라고 하면 첫자리엔 0이 올수 없으므로 일단 dp(1)(?)에 대해 ?엔 1부터 9까지 올 수 있다.
그래서 먼저 반복문으로 처리해주고 각각 1가지씩 되는거니까 1을 가진다.
각각의 dp1,1부터 9에 대해 다음자리에 올 수 있는 수를 구한다.
dp2,?에 대해 ?가 0이면 -1 했을때 음수이므로 +1했을 때만 계단수로가질 수 있고 ?가 9면 +1하면 10이므로 -1했을 때만 가질수 있다.
이 둘을제외하곤 -1, +1을 가질 수있다.
가능한 개수를 구하는건 반대로 생각한다. 트리 dp문제에서 했던것 처럼 예를들어 dp(2)(0)을 만들 수 있는건
dp(1)(1)에서 1뺀거만 가능하니까 수식으로 쓰면
dp(2)(0)+dp(1)(1) 즉 j가 0일때만 dp(i)(j) += dp(i-1)(j+1)이다.
j가 9일 떈 dp(i)(j) += dp(i-1)(j-1)이 된다.
이렇게 입력받은 길이 4에대해 dp(4)(9)까지 다 입력을 받은뒤 최종적으로 끝자리에 0부터 9까지 올 수 있는 수를 다 더해 주면 해당 자리수에서 가능한 계단수의 개수가 나온다.

문제해결

> 자릿수, 끝 수를 가지는 dp 벡터를 이차원으로 선언해준다.
> 맨 앞자리엔 0이 못오므로 dp1에 대해 1부터9까지 미리 지정해준다.
> 두번째 자리부터 반복문을 통해 입력받은 N번째 자리까지 반복하며 0부터 9까지 올 수 있는 수를 탐색한다.
> j가 0일땐, 1에서 빼서 0으로 되는것 뿐이고 9면 8에서 더해서 오는것 뿐이므로 이를 반대로 생각해 j+1과 j-1의 가짓수를 더해준다.
> 이외엔 둘다 더해준다. 마지막으로 1,000,000,000로 각 결과들을 나눠준다.
> dp(N)(9)까지 모두 구한 뒤 이를 0부터 9까지 다 더해준다. N이 1일 때를 생각해보면 한자릿수 일때 가능한 개수는 9개 즉 1부터 9까지이다. 이와 같은 원리로 0부터9까지 더해준다.
> 더해준 결과를 문제조건에 맞게 10억으로 모듈러연산을 하고 출력한다.

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

int Mod = 1000000000;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int N;
	cin >> N;

	vector<vector<long long>> dp(N + 1, vector<long long>(10, 0));
	for(int i = 1; i <= 9; i++) dp[1][i] = 1;

	for (int i = 2; i <= N; i++)
	{
		for (int j = 0; j <= 9; j++)
		{
			if (j == 0) dp[i][j] += dp[i - 1][j + 1];
			else if (j == 9) dp[i][j] += dp[i - 1][j - 1];
			else
			{
				dp[i][j] += dp[i - 1][j - 1];
				dp[i][j] += dp[i - 1][j + 1];
			}
			dp[i][j] %= Mod;
		}
	}
	long long rst = 0;
	for (int i = 0; i <= 9; i++)
	{
		rst += dp[N][i];
	}
	cout << rst % Mod << '\n';
}

후기

길이를 짧게 해서 경우를 모두 따져 따라갔지만 규칙찾는게 복잡했다. 계속 노려보다가 전에 했던 트리문제가 생각이 났다. 비슷한 맥락이었는데 현재 계산해야 될 값을 구하기 위해 반대로 어떤값에서 이 값까지 올 수 있나를 따져봐야 풀리는 것이다. 굉장히 어렵다. dp

0개의 댓글