Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Develop/알고리즘

[백준] 11057 - 오르막 수

sm_amoled 2021. 12. 25. 13:01

문제링크

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

문제

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

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

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

입력

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

출력

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

조건

  • 시간 제한 : 1s
  • 메모리 제한 : 256MB

해설

오르막 수의 자릿수에 따라 증가되는 값의 규칙을 파악하면 쉽게 해결할 수 있다.

1 → 10
2 → 10 + 9 + 8 + ... + 2 + 1
3 → (10+9+...+1) + (9+...+1) + (8+...+1) + ... + 1
...

즉, 1자리수를 제외한 나머지 단계에서는 N[i] = N-1[i ~ 끝까지]의 합이라는 식을 만족한다.

풀이

먼저 계산을 위한 기본 값을 채운다.

vector<long> dp(10);    
	  for(int i = 0; i < 10; i++) {
    dp[i] = 10-i;
}

각 dp의 원소값은 다음 단계(다음 자릿수)로 갈 때 이전 단계에서의 값의 부분합을 이용한다. N[i] = N-1[i ~ 끝까지]의 합를 이용하기 위해 아래와 같이 코드를 작성해준다. 조건에 따라 10007로 나누어 dp에 대입해주어야 한다.

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

결과를 출력하기 위해서는 단계에 있는 원소의 총 합을 10007로 나눈 나머지를 구하면 된다.

long sum = 0;
for(auto x : dp) {
    sum += x;
}
cout << sum%10007 << '\n';


코멘트

[1010 : 다리놓기] 문제의 쉬운 버전이라는 생각이 든다. 규칙만 찾으면 쉽게 풀 수 있는 문제!


코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int N;
    cin >> N;
    
    if(N == 1) {
        cout << 10 << '\n';
        return 0;
    }
    
    vector<long> dp(10);    
    for(int i = 0; i < 10; i++) {
        dp[i] = 10-i;
    }
    
    
    for(int i = 2; i < N; i++) {
        for(int j = 0; j < 10; j++) {
            long temp = 0;
            for(int k = j; k < 10; k++) {
                temp += dp[k];
            }
            dp[j] = temp % 10007;
        }   
    }
    
    
    long sum = 0;
    for(auto x : dp) {
        sum += x;
    }
    cout << sum%10007 << '\n';
 
    
    return 0;
}
320x100

'Develop > 알고리즘' 카테고리의 다른 글

[백준] 2304 - 창고 다각형  (0) 2021.12.25
[백준] 1010 - 다리 놓기  (0) 2021.12.25
[백준] 2812 - 크게 만들기  (0) 2021.12.23
[백준] 2841 - 외계인의 기타 연주  (0) 2021.12.23
[백준] 1935 - 후위 표기식 2  (0) 2021.12.23