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

Pascal Triangle: 이항계수

· 수정 · 📖 약 3분 · 1,023자/단어 #algorithm #math #combinatorics #dp
Pascal Triangle, 파스칼 삼각형, 이항계수, binomial coefficient, 이항 계수

정의

Pascal Triangle 은 각 원소가 위 두 원소의 합인 삼각형. 행 n, 열 k 의 원소가 이항계수 .

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

이항계수 : n 개 중 k 개를 순서 없이 선택하는 경우의 수.

문제 상황

를 팩토리얼로 직접 계산하면:

  • 이 빠르게 오버플로우
  • MOD 연산 시 나눗셈 처리 복잡

해결: 점화식 DP 로 MOD 아래서 정확하게 계산.

재귀 점화식:

경계 조건: .

시각화

flowchart TD
    C00["C(0,0) = 1"]
    C10["C(1,0) = 1"] --> C20["C(2,0) = 1"]
    C00 --> C10
    C11["C(1,1) = 1"] --> C21["C(2,1) = 2"]
    C10 --> C21
    C00 --> C11
    C11 --> C22["C(2,2) = 1"]
    C21 --> C31["C(3,1) = 3"]
    C20 --> C31
    C21 --> C32["C(3,2) = 3"]
    C22 --> C32
    C20 --> C30["C(3,0) = 1"]
    C22 --> C33["C(3,3) = 1"]

핵심 아이디어

DP 계산

2D 배열 C[i][j]에 파스칼 삼각형 저장. 이전 행에서 두 값을 더하는 O(N^2) 방법.

단일 쿼리라면 1D 배열로 공간 최적화:

  • 배열을 오른쪽에서 왼쪽으로 갱신 → in-place 업데이트

MOD 처리

대부분 문제는 답을 로 나눈 나머지 요구.

DP 점화식은 덧셈만 사용하므로 MOD 연산 자연스럽게 적용:

Lucas’ Theorem (대형 n)

n 이 매우 크고 소수 p 로 나눈 나머지를 구할 때:

여기서 , 는 p 진법 표현.

알고리즘

알고리즘 1: 2D 파스칼 삼각형 (O(N^2) 공간/시간)

// C[i][j] = C(i, j) mod MOD
const int MOD = 1e9 + 7;
vector<vector<long long>> C(n + 1, vector<long long>(n + 1, 0));
for (int i = 0; i <= n; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++)
        C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
}
// C[n][k] = C(n, k) mod MOD

알고리즘 2: 1D 공간 최적화 (O(N) 공간)

vector<long long> C(n + 1, 0);
C[0] = 1;
for (int i = 1; i <= n; i++)
    for (int j = i; j >= 1; j--)  // 오른쪽에서 왼쪽으로
        C[j] = (C[j] + C[j-1]) % MOD;
// C[k] = C(n, k) mod MOD

알고리즘 3: 팩토리얼 + 역원 (단일 쿼리 O(N) 전처리)

n 이 크고 다중 쿼리일 때: 팩토리얼과 모듈러 역원을 전처리.

const int MAXN = 2e5 + 5;
const int MOD = 1e9 + 7;
long long fact[MAXN], inv_fact[MAXN];

long long power(long long a, long long b, long long mod) {
    long long res = 1; a %= mod;
    for (; b > 0; b >>= 1) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
    }
    return res;
}

void precompute(int n) {
    fact[0] = 1;
    for (int i = 1; i <= n; i++) fact[i] = fact[i-1] * i % MOD;
    inv_fact[n] = power(fact[n], MOD - 2, MOD);
    for (int i = n - 1; i >= 0; i--) inv_fact[i] = inv_fact[i+1] * (i+1) % MOD;
}

long long C(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n] % MOD * inv_fact[k] % MOD * inv_fact[n-k] % MOD;
}

구현

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;

int main() {
  int n;
  cin >> n;
  // 파스칼 삼각형 출력
  vector<long long> C(n + 1, 0);
  C[0] = 1;
  for (int i = 0; i < n; i++) {
      vector<long long> nxt(n + 1, 0);
      for (int j = 0; j <= i; j++) {
          nxt[j] = (nxt[j] + C[j]) % MOD;
          nxt[j + 1] = (nxt[j + 1] + C[j]) % MOD;
      }
      C = nxt;
      for (int j = 0; j <= i + 1; j++)
          cout << C[j] << " \n"[j == i + 1];
  }
  // C(n, k) 출력
  int k;
  cin >> k;
  cout << C[k] << "\n";
  return 0;
}
stdin
5
2
결과
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
10

성질

성질수식의미
행 합n 개 원소 부분집합 수
홀짝 행 합짝수 선택 수
Hockey stick대각선 합
Vandermonde합성
대칭삼각형 대칭

복잡도

방법시간공간용도
2D DP소규모, n 전체 테이블
1D DP공간 절약
팩토리얼 전처리 전처리, 쿼리다중 쿼리, 대규모
Lucas’ Theorem 쿼리n 극히 크고 소수 MOD

함정

WARNING

MOD 로 나눈 후 나눗셈 불가: MOD 세계에서는 직접 나눗셈 대신 모듈러 역원 사용.

WARNING

k > n 이면 0: 경계 조건 또는 를 반드시 처리.

CAUTION

오버플로우: fact[n] 을 long long 으로 선언해도 n 이 크면 fact[n] * inv_fact[k] 중간에 오버플로우. 각 곱셈마다 % MOD 적용.

흔한 실수

  1. C[i][j] 인덱스 오류: j > i 일 때 0 처리 안 함
  2. 1D DP 갱신 시 왼쪽에서 오른쪽으로 갱신하면 이미 갱신된 값 사용 (오류)
  3. 대형 n 에서 DP 테이블 메모리 초과, 팩토리얼 방법 사용 안 함

BOJ 연습 문제

번호제목키워드
BOJ 11050이항 계수 1기본 계산
BOJ 11051이항 계수 2MOD 계산
BOJ 2608파스칼의 삼각형삼각형 출력
BOJ 18622진수 표현이항계수 응용
BOJ 13977이항 계수와 쿼리팩토리얼 전처리
BOJ 11401이항 계수 3큰 n, 역원

참고

이 글의 용어 (4개)
사칙연산 (Arithmetic Operations)algorithm
정의 사칙연산 (Arithmetic Operations) 은 덧셈, 뺄셈, 곱셈, 나눗셈의 정확한 구현을 다루는 PS 태그. 큰 수 표현 (large integer), 오버플로우…
조합론 (Combinatorics)algorithm
정의 조합론 (Combinatorics) 은 유한 집합의 원소를 세는 수학 분야. PS 에서는 주로 순열 (Permutation), 조합 (Combination), 이항계수 (B…
포함-배제 원리 (Inclusion-Exclusion Principle)algorithm
정의 포함-배제 원리 (Inclusion-Exclusion Principle, PIE) 는 여러 집합의 합집합 크기를 교집합 항으로 표현하는 조합론 공식. 가장 간단한 형태: N…
Catalan Number: C_nalgorithm
정의 Catalan number 는 조합론에서 자주 등장하는 수열. 닫힌 형식(closed form): $$ Cn = \frac{1}{n+1} \binom{2n}{n} = \fr…

💬 댓글

사이트 검색 / 명령어

검색

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