题解 | 《算法竞赛进阶指南》递归实现指数型枚举

【题目】

1 n 1\sim n n ( n 16 ) n (n \leq 16) 个整数中随机选取任意多个,输出所有可能的选择方案。

每行一种方案。同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。对于没有选任何数的方案,输出空行。本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。

【题解】

DFS,即深度优先搜索。深度、优先、搜索。
即可以把单行的输出联想成一条线,而输出的具体内容就是一颗一颗的珍珠。我们要思考的,就是怎么把这一颗颗珍珠串进这根线上。题目要求的是 N N 个数中取任意数按升序排列输出,各行顺序任意。在现实之中,如果我们用手写出来的思路,倒也是有很多种,比如:先从1开始找, 1 , 1 2 1 2 3 1 2 3 4...... 1,1、2,1、2、3,1、2、3、4...... 这样一个个写下去;还有就是从1开始找, 1 , 2 , 3 , 4 , . . . , 1 2 1 3 1,2,3,4,...,1、2,1、3 这样写下去。这个题解,我们来实现一下第二个输出方法。如果是这种输出方法的话,我们就需要让其第一个输出的就是选的数的数量最小的1、2、3、4…,也就是说在dfs遍历到最低层的时候,把需要输出的结果输出。而这就需要我们把深度遍历的优先定为选择的数的个数。这样的话,我们可以把选择珍珠(数字)的方法分为两种:选和不选。而要实现优先输出选择的数量小的,就需要先遍历不选的情况,让其尽可能的不选,直到最后没有办法了,才选了一个,再直到没有办法选一个了,才选两个,一直这样下去。如果看了题解还不明白的,可以结合下面的代码理解一下。

时间复杂度: O ( 2 N ) O(2^N)

#include<iostream>
#include<cstring>
#include<sstream>
#include<string>
#include<cstdio>
#include<cctype>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<list>
#include<set>
#include<map>
#include<algorithm>
#define fi first
#define se second
#define MP make_pair
#define P pair<int,int>
#define PLL pair<ll,ll>
#define lc (p<<1)
#define rc (p<<1|1)  
#define MID (tree[p].l+tree[p].r)>>1
#define Sca(x) scanf("%d",&x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)
#define Scl2(x,y) scanf("%lld%lld",&x,&y)
#define Scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define Pri(x) printf("%d\n",x)
#define Prl(x) printf("%lld\n",x)
#define For(i,x,y) for(int i=x;i<=y;i++)
#define _For(i,x,y) for(int i=x;i>=y;i--)
#define FAST_IO std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define STOP system("pause")
#define ll long long
const int INF=0x3f3f3f3f;
const ll INFL=0x3f3f3f3f3f3f3f3f;
const double Pi = acos(-1.0);
using namespace std;
template <class T>void tomax(T&a,T b){ a=max(a,b); } 
template <class T>void tomin(T&a,T b){ a=min(a,b); }
const int N=16;
int out[20],n;
void dfs(int num,int k){
	if(num==n+1){
		for(int i=1;i<k;i++)
			printf("%d ",out[i]);
		puts("");
		return ;
	}
	dfs(num+1,k);
	out[k]=num;
	dfs(num+1,k+1);
}
int main(){
	Sca(n);
	dfs(1,1);
} 
发布了39 篇原创文章 · 获赞 9 · 访问量 1952

猜你喜欢

转载自blog.csdn.net/qq_36296888/article/details/103125006