티스토리 뷰

Algorithm/BOJ

1038 감소하는 수

henry1214 2018. 9. 20. 22:10

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



d[i][j] = i자리이면서 오른쪽 끝자리가 j인 감소하는 수의 개수 라고 하자. 그러면 d[i][j]는 하나 작은 자리수이면서 끝자리가 j보다 큰 수들에다가 j를 붙이면 된다. 따라서 d[i][j] += d[i-1][k] (j+1<=k<10) 이다. DP로 미리 자리수마다 개수를 세어주고 n번째 감소하는 수가 속하는 자리수를 찾는다. 그 다음 경우의 수를 만들어서 정답을 찾는다.



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
 
int n,i,j,k,d[11][10],cnt[11];
 
int main()
{
    scanf("%d",&n);
    if(n>1022)
    {
        printf("-1\n");
        return 0;
    }
 
    for(j=0;j<10;j++)
        d[1][j]=1,cnt[1]++;
    for(i=2;i<11;i++for(j=0;j<10;j++for(k=j+1;k<10;k++)
        d[i][j]+=d[i-1][k],cnt[i]+=d[i-1][k];
    for(i=2;i<11;i++)
        cnt[i]+=cnt[i-1];
 
    int digit,m;
    for(i=1;i<11;i++)
    {
        if(n<=cnt[i])
        {
            if(n==cnt[i]) m=0,digit=i+1;
            else m=n-cnt[i-1],digit=i;
            break;
        }
    }
 
    string p;
    for(i=0;i<10;i++)
        p.push_back(i<digit?'1':'0');
    vector<string> v;
    do v.push_back(p); while(prev_permutation(p.begin(),p.end()));
    sort(v.begin(),v.end());
    for(i=0,j=9;i<10;i++,j--)
        if(v[m][i]=='1'cout<<j;
    cout<<'\n';
 
    return 0;
}
cs


'Algorithm > BOJ' 카테고리의 다른 글

5639 이진 검색 트리  (0) 2018.11.13
1174 줄어드는 숫자  (0) 2018.09.20
15971 두 로봇  (0) 2018.09.16
11723 집합  (0) 2018.09.13
2098 외판원 순회  (0) 2018.09.13
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday