BP라고 불리는 완전탐색은 단어 그래로 모든 경우의 수를 다 해보는 것이다.
알고리즘을 풀때 강력한 방식이지만, 시간은 최대로 들어간다.
예를들어 비밀번호가 4자리이고 숫자로만 이루어져 있다면, 0 ~ 9999까지 다 해보면된다.
경우의 수는 10,000가지이다. 만약 한 숫자당 1초가 걸린다고 하면 10,000초 = 2.7시간정도가 걸린다.
따라서 완전탐색을 풀기위해서는 대표적으로 4가지를 생각해볼 수 있다.
조합을 이용해서 풀면된다.
나머지를 이용
노가다 문제...
큐 개념도 연습할 수 있다.
서로 다른 n개의 원소에서 r개를 중복을 허용하지 않고 선택하여 순서대로 늘어 놓은 것을 nPr로 표기한다.
참고로 C++에서는 STL nextPermutation을 이용하면 되기 때문에 Java보다 더 쉽게 해결할 수 있다.
ex) 7 2 3 6 5 4 1
public void nextPermutation(int[] arr) {
for (int i = arr.length - 1; i > 0; i--) {
// 끝에서 부터 A[i-1] < A[i]를 만족하는 가장 큰 i 탐색
if (arr[i - 1] < arr[i]) {
// i를 찾았으면 j >= i이면서 A[j] > A[i - 1]를 만족하는 가장 큰 j를 찾는다.
for (int j = arr.length - 1; j >= i; j--) {
if (arr[j] > arr[i - 1]) {
/* A[i]와 A[j]를 swap */
/* A[i]부터 순열을 뒤집는다. */
}
}
}
}
}
다음 순열에서 부등호만 바꿔주면 되는 문제다.
ex) 7 2 3 6 5 4 1
public void previousPermutation(int[] arr) {
for (int i = arr.length - 1; i > 0; i--) {
// 끝에서 부터 A[i-1] > A[i]를 만족하는 가장 큰 i를 탐색
if (arr[i - 1] > arr[i]) {
// i를 찾았으면 j >= i이면서 A[j] < A[i-1]를 만족하는 가장 큰 j를 찾는다.
for (int j = arr.length - 1; j >= i; j--) {
if (arr[j] < arr[i - 1]) {
/* A[i]와 A[j]를 swap */
/* A[j]부터 순열을 뒤집는다. */
}
}
}
}
}
모든 순열 문제는 다음 순열 문제를 활용해서 풀면 간단하게 해결할 수 있다.
유명한 NP문제이다. 풀이법이 상당히 까다로운데 순열문제를 활용하면 된다.
그리고 이 문제는 DFS도 연습할 수 있으므로 2가지 방법으로 풀어보는 것이 좋다.
BFS (너비 우선 검색) 정리 (0) | 2022.03.19 |
---|---|
분할정복(Divide and Conquer) (0) | 2022.03.19 |
동적 계획법 (DP) 정리 (0) | 2022.03.19 |
[OS]프로세스(Process)와 스레드(Thread)의 차이/멀티 프로세스와 멀티 스레드의 개념 ,특징, 장단점 (0) | 2022.03.19 |
[OS]프로세스(Process)와 스레드(Thread)의 차이/멀티 프로세스와 멀티 스레드의 개념 ,특징, 장단점 (0) | 2022.03.19 |