728x90
반응형

문제

45656이란 수를 보자.
이 수는 인접한 모든 자리수의 차이가 1이 난다. 이런 수를 계단 수라고 한다.
세준이는 수의 길이가 N인 계단 수가 몇 개 있는지 궁금해졌다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. (0으로 시작하는 수는 없다.)

입력

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

출력

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

예제 입력 1

1

예제 출력 1

9

예제 입력 2

2

예제 출력 2

17

 

내가 작성한 코드 (C++ 성공)

#include <iostream>
#define mod 1000000000
using namespace std;

int dp[101][10];

int main(){

    int n;
    cin >> n;

    // 1자리 일 때, 1개 이므로 1로 set
    // 0은 올수 없기때문에 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] % mod; // '0' 일 때, '1' 만 가능
            } else if(j == 9){
                dp[i][j] = dp[i-1][j-1] % mod; // '9' 일 때, '8' 만 가능
            } else{
                dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1]) % mod;
            }
        }
    }

    int sum = 0;

    for(int i=0; i<=9; i++){
        sum = (sum + dp[n][i]) % mod;
    }

    cout << sum << "\n";

    return 0;
}

 

풀이

동적계획법에 관한 문제였기 때문에 점화식이 필요했다.
처음에 점화식을 어떻게 구해야하는지 어려웠다.
어떤 문제인지는 알겠는데 이 규칙을 어떻게 식으로 표현하지? 라는 생각이 먼저 들었다.
그렇게 찾은 점화식은

i = 수의 길이 , j = 0~9의 숫자

j = 0	, dp[i][j] = dp[i-1][j+1]
j = 1-8	, dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]
j = 9	, dp[i][j] = dp[i-1][j-1]

더 풀어서 설명해보면

수의 길이 N = 1 ,

0을 제외한 1~9 까지해서 9개의 계단 수가 만들어진다.

1 2 3 4 5 6 7 8 9

수의 길이 N = 2 ,

앞자리에 0이 올 수 없기 때문에 1부터 시작한다.

10 21 32 43 54 65 76 87 98
12 23 34 45 56 67 78 89 --

수의 길이 N=3 ,

101 121 210 232 321 343 432 454 543 565 654 676 765 787 876 898 987
--- 123 213 234 323 345 434 456 545 567 656 678 767 789 878 --- 989

수의 길이가 3 일 때부터 차례대로 살펴보니 어떠한 규칙으로 경우의 수가 증가하는지 알 수 있었다.

길이가 증가할 때, 앞자리 숫자가
0이면 뒤에 1이 오고
9이면 뒤에 8이 오고
1~8이면 뒤에 앞자리 수의 -1 또는 +1
가 온다는 것을 알 수 있었다.

따라서 조건문을 이용해 코드를 작성했다.

if(j == 0){
	dp[i][j] = dp[i-1][j+1] % mod; // '0' 일 때, '1' 만 가능
} else if(j == 9){
	dp[i][j] = dp[i-1][j-1] % mod; // '9' 일 때, '8' 만 가능
} else{
	dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1]) % mod; //  그 외의 숫자
}

그리고 반복문을 이용해 코드를 작성할 수 있었다.

728x90
반응형
복사했습니다!