1.递归实现指数型枚举
从1——n这n(n<20)个数中随机选取任意多个。输出所有可能的方案,
等价于每个整数可以选或者不选,所有的方案为2^n种,DFS思想,选与不选,选了之后要回溯
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n;
vector<int> chosen; //被选择的数
void calc(int x)
{
if(x==n+1){
for(int i=0;i<chosen.size();i++)
printf("%d ",chosen[i]);
printf("\n");
return ;
}
//不选x
calc(x+1); //求解子问题
//选x
chosen.push_back(x); //记录x被记录
calc(x+1); //求解子问题
chosen.pop_back();//还原
}
int main()
{
scanf("%d",&n);
calc(1);
}
2.递归实现排列型枚举
从1——n这n个整数中随机选出m(0<=m<=n<20)个,,输出所有可能的方案
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n,m;
vector<int> chosen; //被选择的数
void calc(int x)
{
if(chosen.size()>m||chosen.size()+(n-x+1)<m){
return ;
}
if(x==n+1){
for(int i=0;i<chosen.size();i++)
printf("%d ",chosen[i]);
printf("\n");
return ;
}
//选x
chosen.push_back(x); //记录x被记录
calc(x+1); //求解子问题
chosen.pop_back();//还原
//不选x
calc(x+1); //求解子问题
}
int main()
{
scanf("%d%d",&n,&m);
calc(1);
}
3.递归实现排列型枚举
把1——n这n个整数排列成一行之后随机打乱,输出所有可能的次序,
全排列问题,所有的可能为N!种,在每次递归中,尝试把每个可用的数作为数列中下一个数,求解n-1个整数安装任意次序排列的这个规模更小的问题
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n;
int order[20]; //按顺序依次记录被选择的整数
bool chosen[20]; //标记被选择的整数
void calc(int k)
{
if(k==n+1){
for(int i=1;i<=n;i++)
printf("%d ",order[i]);
printf("\n");
return ;
}
for(int i=1;i<=n;i++){
if(chosen[i])
continue;
order[k]=i;
chosen[i]=i;
calc(k+1);
chosen[i]=0;
order[k]=0;
}
}
int main()
{
scanf("%d",&n);
calc(1);
return 0;
}