어떻게 풀까?
이 문제는 사전순으로 정렬됐을때, k 번째의 답을 구하는 것과 유사한 문제입니다.
위 문제는 크게 2가지의 경우로 나누어 볼 수 있습니다!
1. 첫 번째로 '-'가 온다.
2. 두 번째로 'o'가 온다.
만약, 장점이 n이고, 단점이 m이라고 했을 때, 총 만들 수 있는 경우의 수를 count(n,m)이라고 합시다!
그러면 첫 번째 경우의 개수는 count(n-1, m)이고, 두 번째 경우는 count(n, m-1) 이 될 것입니다!
그런데, 다시 한번 잘 생각해보면, count의 개수를 쉽게 구할 수 있습니다!
총 n과 m의 길이에서 n개의 위치를 구하는 문제이기 때문에 이항 계수 를 구하면 됩니다!
그렇다면 맨 앞에 'o'가 오는 경우는 언제일까요?
바로! 맨 앞에 '-'가 왔던 경우의 수들 보다 큰 경우 입니다!
'-'를 고를 수 있는 경우의 수들 보다 답으로 내야하는 경우의 수가 크다면, 결국 '-'를 맨 앞에 넣더라도 답이 없다는 것이므로,
해당 개수만큼 세는 경우를 스킵할 수 있습니다!
즉, 맨 앞에 '-'를 넣었기 때문에, 해당 개수는 이 될 것입니다!
그렇다면, n번의 장음과 m번의 단음이 남았고, k번째 답을 골라야할 경우를 choose(n, m, k)라고 합시다!
그렇다면
식을 얻을 수 있습니다.
이를 이용해서 코드를 작성해 봅시다!
시간 복잡도는 우선, 이항 계수를 구하기 위해 O(nm)의 시간이 소요됩니다.
다음에는 choose에서 부분 문제가 n+m개가 나오고 부분문제를 계산할 때 상수 시간이 들기 때문에 O(n +m)이 됩니다.
따라서, 시간복잡도는 O(nm)입니다.
아참! 이항 계수는 굉장히 큰 값이 나오기 때문에 long long을 쓰더라도 오버플로우가 발생합니다!
하지만, k의 값이 10^9 이하이고, 다행히 k를 이용하여 대소 비교만 하기때문에 이항 계수에는 10^9 + 1보다 큰 수가 들어가면
10^9 + 1을 넣어주기만 하면 코드는 문제없이 작동합니다!
이를 이용하는 것도 하나의 팁이라는 사실!
코드
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 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include<cstdio> long long morse[101][101], n, m; long long k; int MORSE() { int t; const char c[2] = { 'o', '-' }; char res[201] = { 0 }; for (int i = 0; i < 101; i++) { morse[i][0] = morse[0][i] = 1; } for (int i = 1; i < 101; i++) { for (int j = 1; j < 101; j++) { //오버 플로우 조심 morse[i][j] = (morse[i - 1][j] + morse[i][j - 1]) > 1000000000000 ? 1000000000000 : (morse[i - 1][j] + morse[i][j - 1]); } } scanf("%d\n", &t); while (t--) { scanf("%lld %lld %lld\n", &n, &m, &k); int idx = n + m; for (int i = 0; i < idx; i++) { // 장점이 남지 않았음. if (n == 0) { res[i] = 'o'; } //맨 앞이 단점 else if (k > morse[n-1][m]) { k -= morse[n-1][m]; m--; res[i] = c[0]; } //맨 앞이 장점 else { n--; res[i] = c[1]; } } res[idx] = 0; printf("%s\n", res); } return 0; } | cs |
'공부 > 알고리즘 문제풀이' 카테고리의 다른 글
[SW Expert Academy] 코드 배틀! (0) | 2018.06.28 |
---|---|
[알고스팟] k번째 최대 증가 부분 수열 (2) | 2018.06.22 |
[SW Expert Academy] N-Queen (0) | 2018.06.21 |
[SW Expert Academy] 장훈이의 선반 (0) | 2018.06.21 |
[SWExpertAcademy] Code Battle (18.8.12 수정) (2) | 2018.06.20 |