알고리즘/백준

[백준 10844번 쉬운 계단 수]

익명의 문과 개발자 2024. 9. 13. 13:58
728x90
728x90

오늘의 문제는 " 쉬운 계단 수"이다.

 

 

#고민의 흐름

처음엔 무조건 완전탐색!

 

어떤 규칙이 있을까 처음부터 고민을 하기 시작했다.

메모장을 켜고 N = 1부터 3 정도까지 ,,

 

생각을 하다 보니 끝자리가 0, 9인 경우만 계단수가 (-1 || +1) 1개만 발생하고

1 ~ 8까지는 (-1 && +1) 2개가 발생한다.

 

오랜만에 종합장을 펴고 이것저것 적어보다 결국 해법을 찾아내었다!

그림과 함께 보자.

 

 

위 사진은 종합장에 내가 적어둔 숫자들이다.

끝자리가 0 ~ 9까지인 수들이

N =? 에 따라 몇 개씩 존재하는지 적어줬다.

여기에서 규칙을 찾아볼 수 있다.

예를 들어, N = 3인 경우 끝자리가 2인 수가 왜 3개냐면,

어쩌면 당연하게도 N = 2일 때 끝자리가 1, 3인 수들의 총개수가 3개이기 때문이다.

 

그렇다. 표처럼 만들고 본인숫자의 대각선 위쪽의 숫자를 더하면

해당 N에서 끝자리가 그 수인 계단수의 개수인 것이다.

이젠 코드를 확인해 보자!

 

코드는 다음과 같다.

( 코드가 너무 커 보인다면 "Ctrl + 스크롤 내리기" 하면 잘 보여요! )

( 초기화는 "Ctrl + 0" / 다시 확대는 "Ctrl + 스크롤 올리기" )

 

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String [] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        long dp [][] = new long [2][10];
        for(int i = 1; i<10; i++){
            dp[0][i] = 1;
        }

        int cnt = 0; // N까지 세주는 cnt
        while(cnt != N){ N자리수가 될때까지 ~
            if(cnt % 2 != 0){ // 홀수일때는 dp[0]에 dp[1]값 더하기
                for(int i = 0; i<10; i++){
                    dp[0][i] = 0;
                    if(i - 1 >= 0){
                        dp[0][i] += dp[1][i-1] % 1000000000;
                    }

                    if(i + 1 <= 9){
                        dp[0][i] += dp[1][i+1] % 1000000000;
                    }
                }
            }else{ // 짝수일때는 dp[1]값에 dp[0]값 더하기
                for(int i = 0; i<10; i++){
                    dp[1][i] = 0;
                    if(i - 1 >= 0){
                        dp[1][i] += dp[0][i-1] % 1000000000;
                    }

                    if(i + 1 <= 9){
                        dp[1][i] += dp[0][i+1] % 1000000000;
                    }
                }
            }
            cnt++;
        }

        long ans = 0; //답에 맞는 dp배열을 모두 더해주고 !
        if(N % 2 == 0){
            for(int i = 0; i<10; i++){
                ans = (ans + dp[1][i]) % 1000000000;
            }
        }else{
            for(int i = 0; i<10; i++){
                ans = (ans + dp[0][i]) % 1000000000;
            }
        }
        System.out.print(ans); // 출력 !
    }
}

 

 

아 이번문제는 진짜 혼자풀 수 있을 줄 알았는데 ,,, 다 풀고 신난 채로 제출하니 1 퍼틀,, 예? 왜요..?

최솟값인 1을 넣어보고 최댓값인 100을 넣어봐도 값이 잘 나왔는데 왜.. 요?

그 이유는 질문게시판에서 찾아볼 수 있었다.

dp값을 모두 구하고 ans에 더할 때만 모듈러 연산을 하는 것이 아닌,

dp값을 구할 때마다 모듈러 연산을 해줘야 한다는 것이다....

이 또한 경험이겠지.. 다음에 큰 수의 dp + 모듈러연산을 하는 경우,

모듈러연산을 모든 연산자리에 넣어줘야겠다.

궁금한 점이 있거나 보충할 점이 있다면 언제든 댓글 부탁드립니다 ~

 

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

 

 

728x90