-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat : [Algorithm] 백트래킹 정리 * fix : 이미지 깨진거 수정
- Loading branch information
Showing
1 changed file
with
53 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
## 백트래킹 알고리즘이란? | ||
|
||
> 해를 찾는 도중 해가 아니어서 막히면, 되돌아가서 해를 찾아가는 기법. | ||
> 최적화 혹은 결정 문제를 푸는 방법 | ||
- 만약 N!의 경우의 수를 가진 문제에서 최악의 경우에는 여전히 지수함수 시간이 필요해서 처리가 불가능할 수도 있음 | ||
- 즉, 모든 경우의 수 중에서 특정한 조건을 만족하는 경우만 살펴보는 것이다. | ||
- 주로 재귀함수로 구현됨 | ||
|
||
### 예시문제 : BOJ 15649 - N과 M(1) | ||
|
||
![image](https://github.com/user-attachments/assets/ddca3413-338b-445c-b527-6c4d07f5442f) | ||
|
||
- 위의 문제를 보면, 무식하게 M중 중첩 반복문으로 탐색을 하고, 각 순열마다 중복 체크를 해서 해결할 수는 있다. | ||
- 그러나, 시간제한을 보면 1초라고 명시되어 있는데, 위의 방법으로 시간복잡도를 계산해보자. | ||
- M중 중첩 반복문을 각 자리에서 N개의 숫자를 모두 시도한다고 했을 때, O(N^M)이다. | ||
- 각 순열마다 중복체크를 한다면 O(M)이다 | ||
- 즉, 도합 O(N^M\*M )의 시간복잡도가 걸리며, 최악의 경우 (N=8,M=8)에는 총1억3천번 정도의 연산을 하게된다 | ||
- 대충 1초 = 1억이라고 치고 계산하면 1.3초 정도 걸리는데, 이러면 시간제한을 맞출 수 없게된다 | ||
|
||
### 해결법 | ||
|
||
``` c++ | ||
void recur (int cnt) { | ||
if(cnt==m) { | ||
for(int i=0;i<m;i++) { | ||
cout << A[i] << " "; | ||
} | ||
cout << '\n'; | ||
} | ||
for(int i=1;i<=n;i++) { | ||
if(vis[i])continue; | ||
vis[i]=true; | ||
A[cnt]=i; | ||
recur(cnt+1); | ||
vis[i]=false; | ||
} | ||
} | ||
``` | ||
|
||
- 위와 같이 재귀호출을 이용해서 구하면 시간 복잡도가 훨씬 줄어들게 된다. | ||
- if(vis[i])continue를 통하여 가지치기(pruning)을 거치면서 연산이 줄어들게 되는것이다. | ||
- 요약하자면 N!/(N-M)! 정도 걸리는데, N=8,M=8인 경우 대략 4만번의 연산을 하게 되므로, 기존의 1억3천번보다 훨씬 줄어든다는 것을 알 수 있다. | ||
|
||
## 추천 문제 | ||
|
||
### N과 M 시리즈(1~9) | ||
|
||
https://www.acmicpc.net/problem/15650 | ||
|
||
### 연산자 끼워넣기 | ||
|
||
https://www.acmicpc.net/problem/14888 |