본문으로 건너뛰기
김신건의 로그

Pigeonhole Principle (비둘기집 원리)

· 수정 · 📖 약 2분 · 790자/단어 #algorithm #math #combinatorics #pigeonhole-principle
pigeonhole principle, 비둘기집 원리, pigeonhole, Dirichlet's principle

정의

비둘기집 원리 (Pigeonhole Principle)“N+1 개의 객체를 N 개의 상자에 넣으면, 적어도 하나의 상자는 두 개 이상의 객체를 포함한다” 는 자명한 조합론 원리. Dirichlet 의 이름을 따 Dirichlet Principle 이라고도 함.

알고리즘 문제에서 “존재성 증명”“최소한 하나는 ~ 하다” 를 주장할 때 핵심 도구.

문제 상황과 동기

단순해 보이지만 비둘기집 원리는 의외로 강력한 문제 해결 도구다.

  • 직관적 사용: “367 명이 있으면 적어도 두 명은 생일이 같다” (366 일)
  • PS 응용: 부분집합 합 문제 (N 개 수에서 어떤 부분집합의 합이 M 의 배수)
  • 극단 원리와 결합: 가장 큰 / 작은 것의 성질 + 비둘기집

핵심 통찰: 무언가가 많으면 반드시 겹치는 구석이 생긴다.

시각화

핵심 아이디어

기본 형태

If n items are placed into m boxes, and n > m,
then at least one box contains at least ceil(n/m) items.

일반화 (강한 형태)

If n items are placed into m boxes, then
there exists a box with at least ceil(n/m) items,
and a box with at most floor(n/m) items.

대우 (contrapositive)

"각 상자에 최대 1 개" = 총 객체 수 ≤ 상자 수

존재 증명: 직접 찾지 않고도 반드시 존재한다고 주장 가능.

알고리즘

비둘기집 원리 적용 패턴:

1. N 개의 객체를 M 개의 "종류" 로 분류 (M < N)
2. 한 종류에 최소 2 개 이상이 존재함을 주장
3. 그 종류가 원하는 성질을 가짐을 보임

대표 예시: "수열의 부분합 중 M 의 배수"
  - 누적 합 S[0..N] (N+1 개)
  - 각 S[i] mod M → M 가지 나머지
  - N+1 > M → 같은 나머지 S[a] ≡ S[b] (mod M)
  - 구간 (a, b] 의 합 = S[b] - S[a] ≡ 0 (mod M)

구현

// 비둘기집 원리: 부분집합 합이 M 의 배수인 경우 찾기
// 누적 합이 같은 나머지 -> 구간 합이 0 (mod M)
#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, m; cin >> n >> m;
  vector<int> a(n);
  for (auto& v : a) cin >> v;

  // prefix sum mod m
  vector<int> first(m, -1);  // 각 나머지의 첫 등장 위치
  first[0] = 0;              // 빈 구간
  int sum = 0;
  for (int i = 0; i < n; i++) {
      sum = (sum + a[i]) % m;
      if (first[sum] != -1) {
          int l = first[sum] + 1, r = i + 1;
          cout << "Found: [" << l << ", " << r << "]\n";
          // 부분 수열 a[l-1..r-1] 의 합이 M 의 배수
          return 0;
      }
      first[sum] = i + 1;
  }
  // 비둘기집에 의해 여기 도달 불가 (N+1 > M 이면)
  cout << "No subset (requires N >= M)" << "\n";
}
stdin
5 3
2 4 1 7 5
결과
Found: [1, 3]

복잡도

항목
비둘기집 사상 (mapping)O(N)
존재 판정O(N)
공간O(M)
일반 확장 (Erdos–Ginzburg–Ziv)O(N)

대표 응용

1. 생일 문제 (Birthday Problem)

23 명: 두 명 생일 같을 확률 > 50%
366 명: 반드시 같은 생일 (비둘기집)

2. Erdős–Ginzburg–Ziv 정리

2n-1 개의 정수에서 적어도 n 개의 합이 n 의 배수.

3. 수열의 부분합

길이 N 수열, N 개 이상의 나머지 M 에 대해
비둘기집으로 같은 나머지 구간 발견.

4. Ramsey 수의 하계

비둘기집 원리는 Ramsey 이론의 기본 빌딩 블록.
R(3, 3) = 6 증명에 사용.

5. 중국인의 나머지 정리와 결합

서로소 M1, M2 ... 의 나머지 배열로 수를 복원.
비둘기집은 주기의 겹침 증명.

함정

1. N > M 조건 착각

비둘기집이 적용되려면 객체 수가 상자 수보다 초과해야 함. 같으면 반드시 겹친다고 할 수 없음.

2. 상자 정의 오류

“상자” 를 잘못 정의하면 원리가 적용되지 않음. 상자는 서로 배타적인 분류여야 함.

3. 존재만 알 뿐 위치는 모름

비둘기집은 존재성만 보장. 구체적인 인덱스나 값을 알려주지 않음. 추가 알고리즘 필요.

BOJ 연습 문제

번호제목정답률링크
BOJ 1037약수-kokoa-lab
BOJ 1940주몽-kokoa-lab
BOJ 2018수들의 합 5-kokoa-lab
BOJ 3273두 수의 합-kokoa-lab

참고

이 글의 용어 (4개)
누적 합 (Prefix Sum)algorithm
정의 누적 합 (Prefix Sum) 은 배열 에 대해 (또는 1-indexed ) 을 미리 계산해 두고, 임의 구간 합 을 O(1) 에 구하는 정형. 문제 풀이에서 "구간 N …
두 포인터 (Two Pointer)algorithm
정의 두 포인터 (Two Pointer) 는 정렬 또는 단조 구조 에서 두 인덱스 , 을 서로 다른 속도 / 방향 으로 이동시키며 부분 구간 / 페어를 O(N) 에 탐색하는 기법…
조합론 (Combinatorics)algorithm
정의 조합론 (Combinatorics) 은 유한 집합의 원소를 세는 수학 분야. PS 에서는 주로 순열 (Permutation), 조합 (Combination), 이항계수 (B…
확률 (Probability)algorithm
정의 확률 (Probability) 은 사건이 발생할 가능성을 수치화한 값. 표본 공간 Ω 에 대해 P(A) = |A| / |Ω| (동일 확률), 또는 더 일반적으로는 σ-alg…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기