| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- ProGuard
- architecture
- Codeforces
- MiTweet
- Kotlin
- GitHub
- Hilt
- 백준
- pandas
- Coroutines
- boj
- activity
- relay
- TEST
- Rxjava
- Coroutine
- 코드포스
- 프로그래머스
- 암호학
- Compose
- livedata
- androidStudio
- 쿠링
- 코루틴
- Gradle
- MyVoca
- textfield
- AWS
- android
- Python
- Today
- Total
이동식 저장소
2248. 이진수 찾기 본문
2248번: 이진수 찾기
N(1 ≤ N ≤ 31)자리의 이진수가 있다. 이러한 이진수 중에서, L(1 ≤ L ≤ N)개 이하의 비트만 1인 것을 크기 순으로 나열했을 때, I번째로 나오는 이진수를 구해내는 프로그램을 작성하시오. 이진수
www.acmicpc.net
$N$자리의 이진수 중에서 1인 비트가 $L$개 이하인 이진수를 오름차순으로 정렬했을 때, $I$번쨰 이진수를 구하는 문제이다. 이진수는 0으로 시작할 수 있음에 주의하자.
이진수를 결정하려면 이진수의 각 자리가 0인지 1인지 결정해야 한다. 현재 자리가 0과 1 중 무엇인지 결정하려면, 현재 자리를 0(또는 1)로 결정했을 때 몇 개의 이진수를 만들 수 있는지 알아야 한다.
문제를 쉽게 만들기 위해, $N$자리의 이진수를 만드는 데 1을 정확히 $L$개 사용한다고 가정하자. 만약 현재 자리를 0으로 결정했다면,하위 $N-1$ 비트에 1을 $L$개 사용할 수 있다. 따라서 매개변수를 $N-1,~L$로 두고 같은 계산을 수행하면 구하는 값을 얻을 수 있다. 어?
반대로 현재 자리를 1로 결정했다면, 하위 $N-1$ 비트에 1을 $L-1$개 사용할 수 있다. 따라서 매개변수를 $N-1, ~L-1$로 두고 같은 계산을 수행하면 구하는 값을 얻을 수 있다. 이제 알겠지? 현재 자리에 0을 놓는 경우의 수와 1을 놓는 경우의 수를 합하면 된다.
그런데 같은 연산이 매개변수만 달리하여 반복되므로 다이나믹 프로그래밍을 적용할 수 있다. 구체적으로 1을 $L$개 사용하여 $N$자리의 이진수를 만드는 경우의 수를 $dp(n,~l)$이라 할 때, $dp(n,~l) = dp(n-1,~l) + dp(n-1,~l-1)$이다.
원래 문제에서는 1을 $L$개 이하로 사용할 수 있으므로, $N$자리의 이진수 중 1을 $L$개 이하로 사용하여 만들 수 있는 이진수의 개수 $sum(n,~l) = \sum_{i=0}^{k}{dp(n,~i)}$로 정의할 수 있다.
이제 이진수를 구해 보자. 현재 자리에 0을 놓았을 때 만들 수 있는 이진수의 개수는 $sum(n-1,~l) = k$개이다. 만약 $I <= k$라면 현재 자리에 0을 놓아야 하고, 그렇지 않다면 1을 놓아야 한다. 높은 자릿수부터 시작해서 이 계산을 반복하면 된다.
맞왜틀 1
$dp$를 계산할 때 terminal case에 주의하자. $n=1$이면 $dp(n,~l) = (l == 0)$이고, $l=0$이면 $dp(n,~l)=1$이다.
맞왜틀 2
$I$는 최대 $2^{31}+1$까지 주어질 수 있다. 따라서 32비트 부호 있는 정수형으로는 입력을 정확히 받을 수 없다. 더 큰 정수형을 사용하거나, 정수 범위에 제한이 없는 언어를 사용해야 한다.
맞왜틀 3
정답을 구할 때, 현재 자리에 1을 놓았다면 $I$에서 $k$를 빼고, $l$을 1 감소시켜야 한다. 0을 놓았다면 아무것도 하지 않아야 한다.

은근히 까다로웠던 문제.
'Problem Solving > BOJ' 카테고리의 다른 글
| 10999. 구간 합 구하기 2 (0) | 2022.10.11 |
|---|---|
| 11562. 백양로 브레이크 (0) | 2022.10.04 |
| 17401. 일하는 세포 (0) | 2022.09.03 |
| 1715. 카드 정렬하기 (0) | 2022.08.31 |
| 3653. 영화 수집 (0) | 2022.08.22 |