포함 배제의 원리 (Inclusion-Exclusion Principle)
포함 배제의 원리는 조합론에서 합집합의 크기를 구할 때 사용하는 공식이다.
그렇다면 합집합의 크기(원소의 개수)를 구하는 방법을 알아보자.
위 그림에서 합집합의 크기를 구하는 방법은 다음과 같다.
$$n(A\cup B\cup C) = n(A) + n(B) + n(C) - \{n(A\cap B) + n(B\cap C) + n(C\cap A)\} + n(A\cap B\cap C)$$
이를 일반화하면 다음과 같은 식이 성립한다.
전체집합의 모든 부분집합의 교집합의 원소를 더하거나 뺄 때, 부분집합의 수가 홀수라면 더하고, 짝수라면 뺀다.
문제
소수의 배수 (BOJ 17436)
https://www.acmicpc.net/problem/17436
17436번: 소수의 배수
첫째 줄에 N(1 ≤ N ≤ 10)과 M(1 ≤ M ≤ 1012)이 주어진다. 둘째 줄에는 N개의 소수가 주어진다. 입력으로 주어지는 소수는 100보다 작거나 같으며, 같은 소수가 두 번 이상 주어지지 않는다.
www.acmicpc.net
코드
더보기
#include <iostream>
#include <cmath>
#include <vector>
typedef long long ll;
using namespace std;
ll n, m, tmp;
vector<ll> v;
int main() {
cin.tie(0); cout.tie(0);
ios_base::sync_with_stdio(false);
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> tmp;
v.push_back(tmp);
}
ll sum = 0;
// 비트마스킹으로 부분집합 구하기
for (int i = 1; i < (1<<n); i++) {
ll lcm = 1;
int odd = -1;
for (int j = 0; j < n; j++) {
if (i & (1<<j)) {
odd *= -1;
lcm *= v[j];
}
}
sum += odd * (m / lcm);
}
cout << sum;
return 0;
}
'알고리즘 > 알고리즘 이론' 카테고리의 다른 글
Monotone Stack, Monotone Queue (단조 스택, 단조 큐) (1) | 2023.11.06 |
---|---|
Network Flow - 네트워크 플로우 (최대 유량 알고리즘) (0) | 2022.08.03 |
Disjoint set, 분리 집합, Union-Find (0) | 2022.03.08 |
탐색 알고리즘(DFS, BFS)과 활용 (0) | 2022.03.05 |
냅색(Knapsack) 알고리즘 (0) | 2022.03.04 |