알고리즘 관련
완전탐색
Andrew-Yun
2020. 12. 14. 22:27
본 글은 프로그래밍 대회에서 배우는 문제해결전략 책과 다른 완전 탐색 구현방법을 보고 정리하는 글이다.
완전 탐색은 다른 말로 brute-force 직역하면 무차별 대입, 모든 경우를 다 구해보는 것이다.
컴퓨터의 장점을 가장 잘 이용하는 방법으로 단순한 문제들을 빠르게 계산할 수 있기 때문에 효율적인 알고리즘을 설계하기 전에 생각해보는 방법이다.
흔히 재귀 호출로 쉽게 구현할 수 있는데, 기저 사례 (base case)의 선택과 상태 공간 트리의 순회방법을 어떻게 구현할 지 고민해야 한다.
(상태공간트리 : 완전 탐색에서 해의 조합들을 트리 (tree) 형태로 나타낼 수 있는데, 부분 문제들을 한 눈에 알 수 있다.)
또한 부분 문제가 또 다른 부분 문제를 구하는 과정에서 쓰일 수 있기 때문에 메모이제이션과 결합하여 연산 속도를 줄이는 방법도 사용될 수 있다.
//n개의 원소 중 m개를 고르는 모든 조합을 찾는 알고리즘
void pick(int n, vector<int>& picked, int toPick)
{
//기저사례 : 더 이상 문제를 분할할 수 없음 (더 고를 원소가 없음)
if(toPick == 0){ printPicked(picked); return; }
//순회 방법 : 가장 작은 원소부터 고름
int smallest = picked.empty() ? 0 : picked.back() + 1;
//반복문으로 순회 구현
for(int next = smallest; next < n; ++next){
picked.push_back(next);
pick(n, picked, toPick - 1);
picked.pop_back();
}
}