알고리즘/PS - 백준

[백준 10844 - C++] 쉬운 계단 수 : 다이나믹 프로그래밍 (DP)

excited-hyun 2021. 2. 19. 10:54
반응형

www.acmicpc.net/problem/10844

 

10844번: 쉬운 계단 수

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

www.acmicpc.net

문제

45656이란 수를 보자.

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

세준이는 수의 길이가 N인 계단 수가 몇 개 있는지 궁금해졌다.

N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. (0으로 시작하는 수는 없다.)

 

입력

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

 

출력

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

 

예제 입력 1 

1

예제 출력 1 

9

 

예제 입력 2 

2

예제 출력 2 

17

 

풀이

1~9는 계단수라고 정해두고 풀이를 시작한다.

계단 수에서 다음 숫자에 j가 오려면 그 전 숫자는 j-1이거나 j+1이어야 한다.

그러나 0과 9에는 j-1또는 j+1이 없다.

따라서 이를 점화식으로 나타내면

i (i >= 2) 길이의 수인 경우

j = 0    f( i , j ) = f( i-1 , 1 )

j = 9    f( i , j ) = f( i-1 , 8 )

j != 0, j != 9   f( i , j ) = f( i-1 , j-1 ) + f( i-1 , j+1 )

위와 같은 식으로 나타낼 수 있다.

이를 코드상에 구현해 주면 끝!

여기서 중요한건 오버플로우가 생기지 않도록 계산중에 계속 1000000000로 %해주어야 한다는 것!

 

#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

long cnt[101][10];

int main(void){
    int n;
    long sum=0;
    scanf("%d", &n);
    for(int i=1; i<10; i++){
        cnt[1][i] = 1;
    }
    for(int i=2; i<=n; i++){
        cnt[i][0] = cnt[i-1][1]%1000000000;
        cnt[i][9] = cnt[i-1][8]%1000000000;
        for(int j=1; j<9; j++){
            cnt[i][j] = (cnt[i-1][j-1]+cnt[i-1][j+1])%1000000000;
        }
    }
    for(int i=0; i<10; i++){
        sum+=cnt[n][i];
    }
    printf("%ld\n", sum%1000000000);
}
728x90
반응형