C++/알고리즘

이항 계수

머슬머슬가이 2025. 4. 5. 14:33

 

개요 :

이항 계수(Binomial Coefficient)란, 주어진 자연수 $n$과 $k$에 대해 “$n$개 중에서 $k$개를 고르는 방법의 수”를 나타내는 값이다. 이는 보통 조합(Combination)으로 불리며, 수학적으로 다음과 같이 정의된다.

 

$
C(n, k) = \frac{n!}{k!(n-k)!}
$

  • $C(n, k)$는 $n$개 중에서 $k$개를 선택하는 경우의 수.
  • $n!$은 $n$의 팩토리얼로, $n \times (n-1) \times \cdots \times 1$을 의미.

원리 :

이항 계수를 풀기 위해서는 점화식을 이용하여 재귀 호출을 해야한다.

 

점화식을 이용한 재귀 방식:
$$
C(n, k) = 
\begin{cases} 
1 & \text{if } k = 0 \text{ or } k = n \\ 
C(n-1, k-1) + C(n-1, k) & \text{otherwise} 
\end{cases}
$$  
점화식을 이용할 경우 중복 계산이 많아 큰 값에 대해 비효율적일 수 있다.
그래서 아래의 방법을 사용하게 된다.

 

동적 계획법:
이전에 계산한 값을 저장하여 중복 계산을 방지하므로 시간 복잡도가 O(n * k)로 최적화됩니다.

  1. 문제를 하위 문제로 분할
  2. 하위 문제들의 해결 결과를 배열에 저장
  3. 이를 반복하여 동일한 문제를 여러번 계산하는 비효율성을 방지

사용 조건 :

  1. $ n $과 $ k $는 자연수여야 합니다.
  2. $ k $는 $ n $보다 작거나 같아야 합니다.
  3. $n $과 $ k $가 커질 경우, 팩토리얼 계산에 필요한 값들이 매우 커질 수 있으므로 계산 효율성을 고려한 알고리즘을 선택하는 것이 중요합니다.

C++ 코드 예시 :

점화식

#include <iostream>

using namespace std;

int main()
{
    int n, k;
    cin >> n >> k;

    long long result = 1;

    if (k > n)
        result = 0;
    else if (k == 0 || k == n)
        result = 1;
    else
    {
        k = (k > n - k) ? n - k : k;

        for (int i = 1; i <= k; ++i)
        {
            result = result * n / i;
            --n;
        }
    }

    cout << result << endl;

    return 0;
}

동적 계획법

using namespace std;

int main()  
{  
int n, k;  
cin >> n >> k;

vector<vector> dp(n + 1, vector(k + 1, 0));

for (int i = 0; i <= n; ++i)  
{  
dp\[i\]\[0\] = 1; // C(i, 0) = 1  
dp\[i\]\[i\] = 1; // C(i, i) = 1  
}

for (int i = 1; i <= n; ++i)  
{  
for (int j = 1; j < i && j <= k; ++j)  
{  
dp\[i\]\[j\] = dp\[i - 1\]\[j - 1\] + dp\[i - 1\]\[j\];  
}  
}

cout << dp\[n\]\[k\] << endl;

return 0;
}

문제 풀어보기 : BeakJoon

'C++ > 알고리즘' 카테고리의 다른 글

유클리드 호제법  (0) 2025.04.05
계수 정렬  (0) 2025.04.05