알고리즘 강의를 보고 정리한 내용입니다.
자기자신을 호출하는 함수
무한루프에 빠지지 않으려면
1. 종료조건을 줘야한다. 적어도 무한루프에 빠지지 않는 하나이상의 경우가 존재해야 한다. (base case)
2. 무한루프를 반복하다 보면 결국 base case로 수렴해야 한다.
수학함수뿐 아니라 다른 많은 문제들을 해결할 수 있다.
코드로 구현하면 이렇게 할 수 있다.
문자열을 하나씩 줄여가면서 ("")에 가까워지는 방식!
적어도 하나의 base case, 즉 순환되지 않고 종료되는 case가 있어야 함
무한루프에 빠지지 않는지 확인해야함
모든 case는 결국 base case로 수렴해야함!!!!!!
암시적 매개변수를 명시적 매개변수로 바꿔라!~!!!
길을 가다가 막다른 길을 만나면 다시 돌아간다.
내가 가장 최근에 내렸던 결정을 번복하고 다른 선택지를 찾는다.
상태공간 트리를 보자.
상태공간 트리의 모든 노드를 탐색해야하는것은 아니다.
내가 선택한 길이 잘못된 길이라는 것을 알게되면 뒤로 돌아가서 다른 선택지를 선택하는것이다.
백트래킹은 깊이우선탐색 방식으로 탐색해서 해를 찾는 알고리즘을 말한다.
https://www.acmicpc.net/problem/15652
문제설명
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 M개를 고른 수열
- 같은 수를 여러 번 골라도 된다.
- 고른 수열은 비내림차순이어야 한다
풀이방법
#include <iostream>
using namespace std;
void go(int cnt, int cur);
int n, m;
int per[8] = { 0, };
int main(void) {
cin >> n; // 전체수
cin >> m; // 순열 개수
go(0, 0);
return 0;
}
void go(int cnt, int cur) {
if (cnt == m) {
for (int i = 0; i < m; i++) {
cout << per[i] << " ";
}
cout << "\n";
return;
}
for (int i = cur; i < n; i++) {
per[cnt] = i + 1;
go(cnt + 1, i);
}
}
위 문제를 이해하기 쉽게 그림으로 구성해 봤는데
1. 레벨 1에서 1이 선택되고, 그다음 레벨 2에서 우선 1이 선택된다.
2. 총 선택된 값의 개수인 2가 m과 동일하기 때문에 레벨2에서 다시 레벨1로 올라간다.(백트래킹)
3. 레벨2단계의 값 중 1은 이미 사용?되었으므로 그다음 값인 2를 선택하게 된다.
4. 위의 2번째 과정이 반복된다.
5. 레벨 2단계의 숫자 3을 선택하는 과정도 같다.
6. 위의 2번째 과정이 반복된다.
7. [1, 1], [1, 2], [1, 3]이 출력되었다. 그래서 레벨1의 선택값이 2가되고, 2에서 선택할 수 있는 레벨2의 값들도 위의 과정과 동일하게 진행되어 [2, 2], [2, 3]이 출력된다.
8. 나머지 과정은 알아서 추론하시길..!