백준

[10844] 쉬운 계단 수

kmyobin 2023. 1. 4. 16:04


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

 

10844번: 쉬운 계단 수

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

www.acmicpc.net

 

DP 문제인데 한참을 헤매다가 다른 사람의 풀이를 참고하였다.

 

직접 써내려가면서 규칙을 찾아보려 했으나 

N=4까지만 보고 규칙을 정한 탓에 틀려버렸다.

	for (int i = 3; i <= N; i++) {
		DP[i] = ((DP[i - 1] - (i - 1)) * 2 + (i - 1)) % 1000000000;
	}

아주 엉터리 규칙이었다.

 

 

숫자가 조금 커져도 금방 오차가 커져버렸기 때문에 다시 처음부터 생각하였다.

 

일단 DP 배열을 2차원으로 선언한다.

N-1자리 계단수에서 마지막 수가 0 또는 9이면, N자리 계단수에서 이를 고려하여 경우의 수를 계산해야 한다.

직접 쓰면서 규칙을 찾았다.

i가 0이나 9가 아니면 DP[i-1][j-1]+DP[i-1][j+1]를 하면 된다.(파란색 화살표 참고)

i가 0 또는 9이면 방식이 좀 달라진다.

 

하지만 숫자가 금방 커지기 때문에 오버플로우가 발생한다.

따라서 unsigned long long으로 자료형을 바꾸고 1,000,000,000으로 나눈 나머지를 출력하였다.

 

이를 따른 코드는 아래와 같다.

#include <iostream>
using namespace std;

int N;
unsigned long long DP[101][10];
unsigned long long sum;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> N;

	/* 초기값 설정 */
	for (int i = 0; i <= 9; i++) {
		if (i == 0)DP[1][i] = 0;
		else 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] % 1000000000;
			else if (j == 9) DP[i][j] = DP[i - 1][j - 1] % 1000000000;
			else DP[i][j] = (DP[i - 1][j - 1] + DP[i - 1][j + 1]) % 1000000000;
		}
	}

	for (int i = 0; i <= 9; i++) {
		sum += (DP[N][i]);
	}
	cout << sum % 1000000000;

}