순열, 조합에 대한 더 자세한 설명은 👉 DFS로 순열 및 조합 구현 ( blahblahlab.tistory.com/28 )
(1) 순열
N개 중에 중복없이 M개를 고른다 & 수열사이 대소관계는 없다 (오름차순 혹은 내림차순)
👉 nPm 순열을 얘기하는거다
중복이 없어야 하므로 VISITED 배열을 이용해 방문여부를 따져야한다.
또 오름차순 내림차순과 같은 관계가 없으므로 항상 1부터 시작해도 된다.
N을 입력받으면 1 ~ N 까지의 수로 순열을 만들면 되기 때문에 별다른 배열 없이 인덱스로만 구성하면 된다.
#include <iostream>
#include <vector>
using namespace std;
int n, m;
vector<int>temp;
int visited[9] = { false };
void backtracking(int cnt) {
if (cnt == m) {
for (int i = 0; i < temp.size(); i++) printf("%d ", temp[i]);
printf("\n");
return;
}
for (int i = 1; i <= n; i++) {
if (visited[i]) continue;
visited[i] = true;
temp.push_back(i);
backtracking(cnt + 1);
temp.pop_back();
visited[i] = false;
}
}
int main() {
scanf("%d %d", &n, &m);
backtracking(0);
}
2) 조합
N개 중에 중복없이 M개를 고른다 & 수열은 오름차순이어야한다
👉 nCm 조합을 얘기하는거다.
중복이 없어야 하므로 VISITED 배열을 이용해 방문여부를 따져야한다.
또 오름차순이어야하므로 만약 3을 뽑았다면 3보다 큰 숫자들이 뒤에 나와야한다. 그렇기 때문에 시작하는 인덱스를 늘리며 계산해주어야한다.
N을 입력받으면 1 ~ N 까지의 수로 순열을 만들면 되기 때문에 별다른 배열 없이 인덱스로만 구성하면 된다.
#include <iostream>
#include <vector>
using namespace std;
int n, m;
vector<int>temp;
int visited[9] = { false };
void backtracking(int cnt , int idx) {
if (cnt == m) {
for (int i = 0; i < temp.size(); i++) printf("%d ", temp[i]);
printf("\n");
return;
}
for (int i = idx; i <= n; i++) {
if (visited[i]) continue;
visited[i] = true;
temp.push_back(i);
backtracking(cnt + 1 ,i+1);
temp.pop_back();
visited[i] = false;
}
}
int main() {
scanf("%d %d", &n, &m);
backtracking(0 ,1);
}
3) 중복순열
같은 수를 여러번 골라도 된다 (중복가능) & 오름차순과 같은 관계가 없다
👉 nPIm 중복순열을 얘기하는거다.
중복가능하므로 방문여부를 따질 필요 없다.
또 오름차순 내림차순과 같은 관계가 없으므로 항상 1부터 시작해도 된다.
N을 입력받으면 1 ~ N 까지의 수로 순열을 만들면 되기 때문에 별다른 배열 없이 인덱스로만 구성하면 된다.
#include <iostream>
#include <vector>
using namespace std;
int n, m;
vector<int>temp;
int visited[9] = { false };
void backtracking(int cnt) {
if (cnt == m) {
for (int i = 0; i < temp.size(); i++) printf("%d ", temp[i]);
printf("\n");
return;
}
for (int i = 1; i <= n; i++) {
temp.push_back(i);
backtracking(cnt + 1);
temp.pop_back();
}
}
int main() {
scanf("%d %d", &n, &m);
backtracking(0);
}
4) 중복조합
같은 수를 여러번 골라도 된다 & 비내림차순 ( 같거나 점점 커진다 )
👉 nHm 중복조합을 얘기하는거다.
중복가능하므로 방문여부를 따질 필요 없다.
또 오름차순이어야하므로 만약 3을 뽑았다면 3보다 큰 숫자들이 뒤에 나와야한다. 그렇기 때문에 시작하는 인덱스를 늘리며 계산해주어야한다.
N을 입력받으면 1 ~ N 까지의 수로 순열을 만들면 되기 때문에 별다른 배열 없이 인덱스로만 구성하면 된다.
#include <iostream>
#include <vector>
using namespace std;
int n, m;
vector<int>temp;
int visited[9] = { false };
void backtracking(int cnt, int idx) {
if (cnt == m) {
for (int i = 0; i < temp.size(); i++) printf("%d ", temp[i]);
printf("\n");
return;
}
for (int i = idx; i <= n; i++) {
temp.push_back(i);
backtracking(cnt + 1 , i);
temp.pop_back();
}
}
int main() {
scanf("%d %d", &n, &m);
backtracking(0 , 1);
}
'알고리즘 > 백준 단계별로 풀기 (12.26 ~ 12.31)' 카테고리의 다른 글
BFS 및 DFS - 백준 7569번 토마토 (3차원) (0) | 2020.12.27 |
---|---|
BFS 및 DFS - 백준 7576번 토마토 (0) | 2020.12.27 |
다이나믹프로그래밍1 - 백준 1904번 01타일 (0) | 2020.12.27 |
다이나믹프로그래밍1 - 백준 9461번 파도반 수열 (0) | 2020.12.27 |
다이나믹프로그래밍1 - 백준 2748번 피보나치 수 2 (0) | 2020.12.27 |