BOJ 백준/다이나믹 프로그래밍

[BOJ] 11057번: 오르막 수

코블리_vv 2022. 8. 16. 15:28
728x90
반응형

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

 

11057번: 오르막 수

오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이때, 인접한 수가 같아도 오름차순으로 친다. 예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다. 수

www.acmicpc.net

문제

오르막 수는 수의 자리가 오름차순을 이루는 수를 말한다. 이때, 인접한 수가 같아도 오름차순으로 친다.

예를 들어, 2234와 3678, 11119는 오르막 수이지만, 2232, 3676, 91111은 오르막 수가 아니다.

수의 길이 N이 주어졌을 때, 오르막 수의 개수를 구하는 프로그램을 작성하시오. 수는 0으로 시작할 수 있다.

 

입력

첫째 줄에 N (1 ≤ N ≤ 1,000)이 주어진다.

 

출력

첫째 줄에 길이가 N인 오르막 수의 개수를 10,007로 나눈 나머지를 출력한다.

 


풀이

📌 다이나믹 프로그래밍 (DP)

 

dp[i][j]를 길이가 i이고 j로 끝나는 오르막의 수라 하자.

 

j가 0일 경우 길이가 뭐든지 간에 오르막의 수는 1이다.

길이가 1이고 j로 끝나는 모든 오르막의 수는 1이다.

따라서 길이가 1인 오르막 수의 개수는 dp[1][j]인 경우를 모두 더해 총 1*10 = 10 개다.

 

길이가 2인 경우를 살펴보자.

0으로 끝나는 경우 1가지

1로 끝나는 경우 = 길이가 1이고 0으로 끝나는 경우 + 길이가 1이고 1로 끝나는 경우

2로 끝나는 경우 = 길이가 1이고 0으로 끝나는 경우 + 길이가 1이고 1로 끝나는 경우 + 길이가 1이고 2로 끝나는 경우

...

j로 끝나는 경우는 길이가 1인 것들 중에서 0~j로 끝나는 경우들을 모두 합친 결과이다.

dp[i][j] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2] + dp[i-1][3] + dp[i-1][4] + ...

          =  dp[i-1][j] + dp[i][j-1]

 

길이가 n인 오르막 수의 개수는 dp[n][0]~dp[n][9]의 결과를 모두 더한 값이다.

 

코드

#include <iostream>
using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  int n;
  //dp[i][j]는 길이가 i고 j로 끝나는 오르막의 수
  long long dp[1002][10];
  cin >> n;

  for(int i = 1; i <= n+1; i++) {
    for(int j = 0; j < 10; j++) {
      if(j == 0 || i == 1) dp[i][j] = 1;
      else {
        dp[i][j] = (dp[i-1][j] + dp[i][j-1]) % 10007;
      }
    }
  }

  cout << dp[n+1][9];
  return 0;
}

 

결과

 
728x90
반응형