본문 바로가기

Tech/Problem Solving

[백준 11057] 오르막 수 (Java)

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

 

11057번: 오르막 수

오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이때, 인접한 수가 같아도 오름차순으로 친다. 예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다. 수의 길이 N이 주어졌을 때, 오르막 수의 개수를 구하는 프로그램을 작성하시오. 수는 0으로 시작할 수 있다.

www.acmicpc.net

접근 방법

전형적인 DP문제라고 하는데 역시나 아직 많이 부족함을 느낀다.

 

2차원배열을 사용한다.

dp[N][0~9]로 수의 길이가 N번일 때, 마지막 자리수가 0 ~ 9 경우의 개수를 각각 담는다.

 

우선 dp[1][0~9]는 모두 1로 따로 설정을 해둔다.

for문을 이용해 2부터 N까지 돌려 값을 구한다.

 

dp[2]의 경우를 예로 들어보자

dp[2][0]은 마지막 자리의 수가 0인 경우 오르막 수 갯수를 구한다.

이 경우에는 00 하나만 존재한다.

 

dp[2][1]은 마지막 자리 수가 1인 경우 오르막 수 갯수를 구한다.

이 경우에는 01, 11이 존재한다.

 

dp[2][2]은 마지막 자리 수가 2인 경우 오르막 수 갯수를 구한다.

이 경우에는 02, 12, 22가 존재한다.

 

dp[2][i]에는 0i ~ ii가 존재한다.

마지막 자리 수가 없다 생각하고 수의 변화를 살펴보면

0일 때 0

1일 때 0과 1

2일 때 0, 1, 2

3일 때 0, 1, 2, 3

...

 

이를 일반화 시키면 다음과 같은 점화식이 나온다.

dp[n][i] = dp[n -1][0] + ... + dp[n-1][i]

 

3중 for문을 구해 배열의 각 값을 구하고

dp[n][0] ~ dp[n][9]의 값을 더한 것에 10007을 나눠 나온 나머지를 출력하면 된다.

 

 

소스 코드

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt();
        int[][] dp = new int[N + 1][10];


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

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

        int result = 0;

        for (int i = 0; i < 10; i++) {
            result += dp[N][i];
        }

        System.out.println(result % 10007);
    }
}

 

반응형

'Tech > Problem Solving' 카테고리의 다른 글

[백준 2805] 나무 자르기 (Java)  (0) 2020.04.04
[백준 2217] 로프 (Java)  (0) 2020.03.09
[백준 11052] 카드 구매하기 (Java)  (0) 2020.03.06
[백준 2156] 포도주 시식 (Java)  (0) 2020.03.05
[백준 2293] 동전 1 (Java)  (0) 2020.03.04