1.指数型 DFS(子集型)
C++代码
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int n;
int st[N]; //表示当前位置的状态,0表示未考虑,1表示选,2表示不选
void dfs(int u){
if(u > n){
for(int i = 1; i <= n; i++){
if(st[i] == 1) printf("%d ",i);
}
puts("");
return; //结束当前的搜索
}
//第一个分支:选
st[u] = 1;
dfs(u + 1);
st[u] = 0;
//第二个分支:不选
st[u] = 2;
dfs(u + 1);
st[u] = 0;
}
int main(){
scanf("%d",&n);
dfs(1); //从第一个位置开始考虑
return 0;
}
2.排列型DFS
C++代码
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n;
int path[N]; //存每个方案
int st[N]; //标记每个数字的使用情况
void dfs(int u){
if(u > n){
for(int i = 1; i <= n; i++){
printf("%d ",path[i]);
}
puts("");
return;
}
for(int i = 1; i <= n; i++){
if(st[i] == 0) { //如果当前数字未使用过
st[i] = true; //使用当前数字
path[u] = i;
dfs(u + 1);
st[i] = false; //恢复现场
path[u] = 0;
}
}
}
int main(){
scanf("%d",&n);
dfs(1); //从第一个位置开始搜索
return 0;
}
3.组合型DFS
C++代码
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int n,m;
int path[N]; //记录方案
void dfs(int u,int start){ //u表示当前搜索的位置,start 表示
//剪枝!
if(u + n - start < m) return;
if(u > m){
for(int i = 1; i <= m; i++){
printf("%d ",path[i]);
}
puts("");
return;
}
for(int i = start; i <= n; i ++){
path[u] = i;
dfs(u + 1, i + 1); //当前选的数是i,因此下一个搜索从i + 1个位置开始
path[u] = 0; //恢复现场
}
}
int main(){
scanf("%d%d",&n,&m);
dfs(1,1);
return 0;
}