티스토리 뷰

반응형

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

 

1256번: 사전

동호와 규완이는 212호에서 문자열에 대해 공부하고 있다. 김진영 조교는 동호와 규완이에게 특별 과제를 주었다. 특별 과제는 특별한 문자열로 이루어 진 사전을 만드는 것이다. 사전에 수록되

www.acmicpc.net

 

필요한 배경지식

  • 다이나믹 프로그래밍
  • 조합론 - 파스칼 항등식

 

문제 해결 방법

N=2, M=2 일때 나올 수 있는 문자열을 사전순으로 나열하면 다음과 같습니다.

 

1번째 문자열 : aazz

2번째 문자열 : azaz

3번째 문자열 : azza

4번째 문자열 : zaaz

5번째 문자열 : zaza

6번째 문자열 : zzaa

문제에서 K=2로 주어진다면 2번째 문자열인 azaz를 출력해야 합니다. 어떻게 출력해야 할까요 ?

 

첫번째 문자부터 마지막 문자까지 하나씩 출력하여 2번째 문자열을 출력할 수 있는 방법을 생각해 보겠습니다.

위의 경우 첫번째 문자로 'a'가 온다면

남은 문자열로 만들 수 있는 3개의 문자열중 2번째 문자열이 포함되어 있으므로  'a'를 출력,

그 다음 두번째 문자열로 'a'가 온다면

남은 문자열로 1개의 문자열만 만들어 낼 수 있고 이것은 2번째 문자열이 아니므로 'a'대신 'z'를 출력,

그 다음의 문자열들도 같은 방식으로 출력하여 azaz를 출력할 수 있습니다.

 

이제 주어진 'a'와 'z'로 만들어 낼 수 있는 문자열의 개수만 알면 됩니다.

이것은 조합을 이용하면 쉽게 구해낼 수 있습니다.

문자열은 'a'와 'z' 두개뿐이므로 총 문자열의 개수에서 'a'또는 'z'가 위치할 자리의 개수만 뽑으면 됩니다.

예를들어 'a'문자 5개, 'z'문자 3개로 만들 수 있는 문자열의 총 개수를 알고 싶다면 8C5 또는 8C3를 계산하면 되겠죠.

 

이때 조합의 계산은 파스칼 항등식과 DP를 이용하여 구현했고

1 ≤ K ≤ 1,000,000,000 라는 조건이 있기 때문에 조합의 계산 결과가 K의 범위를 넘어가면

INF라는 상수를 반환하도록 구현했습니다.

 

 

전체코드

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9 + 1;

int N,M,K;
ll dp[210][110]{};

// 탑다운 DP
ll comb(int n, int r) {
    if(n==r || r==0) return 1;
    ll &ret = dp[n][r];
    if(ret==0) {
        ll tmp = comb(n-1, r-1) + comb(n-1, r);
        ret = tmp >= INF ? INF : tmp;
    }
    return ret;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M>>K;
    if(comb(N+M,M) < K) {cout<<-1; return 0;}
    
    int cn = N, cm = M, ck = K;
    for(int i=0; i<N+M; i++){
        if(cn==0) {cout<<'z'; continue;}
        ll now = comb(cn+cm-1, cn-1);
        if(now >= ck) {
            cout<<'a';
            cn--;
        } else {
            cout<<'z';
            ck -= now;
            cm--;
        }
    }
}

 

반응형

'알고리즘 공부 > 문제풀이' 카테고리의 다른 글

백준 2624번 - 동전 바꿔주기  (0) 2022.01.22
백준 10564번 - 팔굽혀펴기  (0) 2022.01.13
백준 14226번 - 이모티콘  (0) 2021.07.10
백준 1017번 - 소수 쌍  (0) 2021.06.09
백준 4991번 - 로봇 청소기  (0) 2021.06.01
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함