10844

백준 10844번

Link: 10844번: 쉬운 계단 수


문제 설명

어제는 피곤함에 빈둥거리다 아무것도 못올렸다.

이 문제는 어제부터 고민하다 방법을 찾았고, 그 방법을 어떻게 구현할지 많은 시행착오를 거친 끝에 결국 풀었다.

사실 맨 마지막에 내 생각이 확실한데 답이 자꾸 틀려서 다른사람 답을 찾아보긴 했지만, 그 답이 내가 생각한 그대로여서 여태껏 답 찾아본 문제들중 가장 치열하게 고민한 문제인 것 같다는 생각을 했다.

그만큼 이번에는 답찾아서 풀었음에도 쪽팔리다는 생각이 들지 않았고.

각설하고, 푸는 방법에 대해 설명해보자면 이 문제에서 각 자릿수가 몇자리수이냐는 아무 상관이 없다.

가장 중요한 것은 1의자리 숫자가 무엇인지.

N이 1일때, 2일때, 3일때의 경우들을 직접 구해보니 1의자리 숫자에 따라 다음 수가 영향을 받는다는 것을 알 수 있었다.

자꾸 보다보니 N일때의 답 = (N-1일때의 답 * 2) - (N-1일때의 계단수 중 첫자리 숫자가 1인 것의 갯수) 라는 규칙을 찾은것같은데, 맞는지는 모르겠다.

어떻게 구현할지 한참 고민하다 저 규칙대로 풀어보기 위해 우선 큐에 넣고 갱신해가면서 모든 경우를 다 돌려봤다.

한 5분은 지나야 전체 답을 구할 수 있더라.

이런 과정을 거치면서 이 문제를 어떻게하면 이전 N에서 얻은 답을 사용할수 있을지에 대해 중점적으로 고민해보았고, 결국 1의자리 숫자만이 영향을 미친다는 점을 찾기에 이르렀다.

이 문제를 풀며 가장 고무적이었다고 생각했던 부분은 DP의 특성을 어떻게든 적용하기 위해 노력했다는 점.

앞에서 구한 답을 어떻게 써먹을수 있는지 그 어느때보다 치열하게 고민한 것 같다.

이 문제를 풀어낸 것이 앞으로 DP문제를 푸는데 있어 전환점이 되길!!


정답 코드

//
// Created by Keith_Lee on 08/01/2019.
//

#include <iostream>
#include <strings.h>

using namespace std;

int main(){
    int N;

    cin >> N;

    unsigned long long DP[101][11];
    bzero(DP, sizeof(DP));

    for(int i=1; i<10; i++){
        DP[1][i] = 1;
    }

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

    unsigned long long sum = 0;
    for(int i=0; i<10; i++){
        sum += DP[N][i];
    }
    cout << (sum % 1000000000) << '\n';

    return 0;
}

Tags:

Categories:

Updated: