이진수 찾기

[이진수 찾기] (https://www.acmicpc.net/problem/2248)

N(1≤N≤31)자리의 이진수가 있다. 이러한 이진수들 중에서, L(1≤L≤N)개 이하의 비트들만 1인 것들을 크기 순으로 나열했을 때, I번째로 나오는 이진수를 구해보자 이진수는 0으로 시작할 수도 있다.

N개 자리수 중 1비트가 L개 이하인 수 중 I번째 인 것은? 모스 부호 사전 문제와 유사

N:4, L=2, I=4 라면 다음과 같은 경우의 수가 나올 수 있다

  • L 이 1인 경우 0001
    0010
    0100
    1000
  • L 이 2인 경우 0011
    0101
    0110
    1001
    1010
    1100
for (int i = 0; i <= N; i++) {
    for (int j = 0; j <= Math.min(i,  L); j++) {
        if (i == 0 || j == 0 || i == j) {
            d[i][j] = 1;
        } else {
            d[i][j] = d[i - 1][j] + d[i - 1][j - 1];
        }
    }
}

while (N != 0)  {
    long sum = 0;
    for (int i = 0; i <= L; i++) {
        // 선택한 수가 0일 때, 가질 수 있는 1의 경우 수
        sum += d[N - 1][i];
    }
    if (sum >= I) {
        System.out.print("0");
        N--;
    } else {
        System.out.print("1");
        I = I - sum;
        L--;
        N--;
    }
}
PADI 강사 개발코스

PADI IDC 비용

전체금액 알기 어렵고 잘 오픈안한다. 실제로 뭐가 포함되는지 불포함인지 ㅇ잘 알지 못한다

IDC 비용

  • IDC 비용 강사과정 & EFR 강사과정 & 2주 숙식 보통 최소 1500불 ~ 2500불
  • IDC 교재 비용 강사 패키지 + EFR 강사팩 = 코스 디렉터 마음 (45만~80만원)
  • PADI 단체에 지불하는 시험비용 및 등록비용 OWSI 강사 등록 / AI 보조강사 등록비용 / EFR 강사 등록비용 = 1400불

IDC 패키지 잘 따져야 ..추가 교육여부

레벨

  • OWSI(Openwater Scuba Instructor): 막 통과할 때 되는 레벨
  • SI
  • MSDT: 스페셜티 코스 등 까지 모드 가르치는 레벨 갱신 된 PADI 강사 최소 5개의 PADI 스페셜티 강사자격 최소 25명의 다이버 인정증 발급경험

  • IDC STAFF

  • MI
  • Course Director
사회망 서비스

사회망 서비스

얼리 어댑터인지 아닌지 2개의 상태가 주어진다

  • root i 가 얼리어답터일 경우: i의 child node는 얼리어답터일 수도 있고 아닐 수도 있다

  • root i가 얼리어답터가 아닐 경우: i의 child node는 무조건 얼리어답터이어야 한다

d[i][state]: state 0일 때 정점이 얼리어답터가 아닌경우, otherwise 1

d[i][0] = 0 d[i][0] += d[child][1]

d[i][1] = 1 d[i][1] += min(d[child][0], d[child][1])

최상위 root node가 1일 경우 해는 min(d[1][0], d[1][1]) 이다

leaf에서부터 시작한다

private static void sns(int curr) {
    d[curr][1]++;
    visited[curr] = true;
    
    for (int next: adj.get(curr)) {
        if (visited[next] == false) {
            sns(next);
            d[curr][0] += d[next][1];
            d[curr][1] += Math.min(d[next][0], d[next][1]);
        }
    }
}

이런 구현도 가능하다

private static int sns(int curr, int adt) {
    if (d[curr][adt] != -1) {
        return d[curr][adt];
    }
    visited[curr] = true;
    if (adt == 1) {
        d[curr][adt] = 1;
        for (int next: adj.get(curr)) {
            if (visited[next] == false) {
                d[curr][adt] += Math.min(sns(next, 0), sns(next, 1));
            }
        }
    } else {
        d[curr][adt] = 0;
        for (int next: adj.get(curr)) {
            if (visited[next] == false) {
                d[curr][adt] += sns(next, 1);
            }
        }
    }
    visited[curr] = false;
    return d[curr][adt];
}

사람별 얼리어댑터인지 아닌지 trace를 해보자

RGB거리

RGB거리

d[n][3] // 각 R G B로 n개의 집을 칠하는데 드는 비용의 최솟값

d[3][0] 은 3개의 집에 마지막 집이 R 일 때 드는 비용의 최솟값이다.

d[3][0] 은 d[2][1] + d[1][2] or d[2][2] + d[1][1] 중 최솟값 에 현재 R일 때 비용

d[n][0] = min(d[n-1][1] + d[n-2][2], d[n-1][2] + d[n-2][1]) + a[n][0]

for (int i = 1; i <= N; i++) {
    d[i][0] = Math.min(d[i - 1][1], d[i - 1][2]) + map[i][0];
    d[i][1] = Math.min(d[i - 1][0], d[i - 1][2]) + map[i][1];
    d[i][2] = Math.min(d[i - 1][0], d[i - 1][1]) + map[i][2];
}

각 마을을 어떤 색으로 칠해야 하나?

이친수

이친수

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 들 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다.

이친수는 0으로 시작하지 않는다. 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11을 부분 문자열로 갖지 않는다. 예를 들면 1, 10, 100, 101, 1000, 1001 등이 이친수가 된다. 하지만 0010101이나 101101은 각각 (1), (2)번 규칙에 위배되므로 이친수가 아니다.

이와 같은 이친수를 이진수의 크기 순서대로 정렬하여 차례로 번호를 붙인다. 이를테면 첫 번째 이친수는 1, 두 번째 이친수는 10, 네 번째 이친수는 101이 되는 식이다.

N(1≤N≤90)이 주어졌을 때, N자리 이친수의 개수

1: 1 = 1
2: 10 = 1
3: 100 101 = 2
4: 1000 1001 1010 = 3
5: 10000 100001 10010 10100 10101 = 5
6: 2 + 1 + 2 + 2 + 1 = 8

마지막 수는 0 또는 1이 올 수 있고, 0과 1에 따라 식이 나눠진다.

dp[n][2] // n번째 자리에 0 or 1이 왔을 때 의 이친수의 갯수 로 정의

d[1][0] = 0
d[1][1] = 1

d[n][0] = d[n-1][0] + d[n-1][1]
d[n][1] = d[n-1][0]

다른 풀이로는 8 (n) = 5 (n-1) + 3 (n-2) 임을 쉽게 알 수 있다.

이친수 찾기

위 문제에서 자연수 K(1≤K≤1,000,000,000,000,000,000)가 주어졌을 때, K번째 이친수를 찾아내는 프로그램을 작성하시오.