递归实现指数型枚举
做题思路
-
创建一个空间存储要便利的个数状态
如要枚举3个数的所有排列组合,那要创建三个空间,来存储每个数的状态
-
开始枚举
要枚举三个数的所有组合,那么就要便利所有的情况,那么每一个数都有选和不选两种情况所以每一个数都要分两种情况进行递归
-
最后终止的条件是枚举的个数不超过三个(三个数进行枚举,可选可不选,所以所选择的个数可以是1~3个)
理解
采用递归的思路,就是:
看要枚举几个数,几个数他递归的层数就是几层
因为每个数只有选和不选两种情况,所以他的分支只有两个,是一个二叉树
然后进行先序遍历,遍历到三个的时候就会输出当前遍历的结果。
递归:
一层有几个分支,那么递归函数里面就会有几个递归函数
然后需要递归几层就在终止条件那边进行判断:
代码(用参数保存状态)
#include<iostream>
using namespace std;
int n;
void dfs(int u,int state)
{
if(u == n)
{
for(int i = 0; i < n; i++)
if(state >> i & 1)
cout<<i + 1<<" ";
cout<<endl;
return;
}
dfs(u+1,state);
dfs(u+1,state| 1 << u);
}
int main()
{
cin>>n;
dfs(0,0);
return 0;
}
代码(用全局变量保存状态)
#include<iostream>
using namespace std;
int n;
int st[16];
void dfs(int u)
{
if(u == n)
{
for(int i = 0; i < n; i++)
if(st[i] == 1)
cout<<i + 1<<' ';
cout<<endl;
return;
}
st[u] = 1;
dfs(u+1);
//st[u] = 0; 这里是要恢复现场的,因为要保证进入下一个分支的时候是由根节点的状态进入的
//但是这边只有两个分支,选跟不选,所以可以省略
st[u] = 0;
dfs(u+1);
//st[u] = 0;
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
当改变树的状态的时候需要恢复现场,要保证进入下一个分支的时候是以根节点的状态进入的,而不是兄弟节点回溯完的状态进入的