递归实现指数型枚举

问题描述

给你一个正整数,从中选取任意多个数,打印所有选法。

对于每种选法,从小到大输出所选的数。

样例输入

样例输出

这道题有特判,只需要输出了每组测试数据、每组数据中的数是从小到大的即可。

解题思路

这里介绍两种方法:一种正如题面所说,用递归实现;另一种借助前面介绍的求二进制状态下哪几位是1的方法通过状态压缩来实现。

方法一

每个数都能选与不选。定义一个vector来记录选择了哪些元素;定义一个函数calu(int x)表示该处理第x个元素了。

当x>n时,说明已经处理完n个元素了,就之间打印。

否则,分别对 选 与 不选 第x个元素进行递归,若选就push到vector中,不选就不push。记得递归结束pop出来保留现场。

方法二

用0~2n这2n个数代表每个元素的选与不选。每个数代表一种状态。对于一个状态数x,x的第j位若为0就代表不选元素j+1,否则为1代表选择元素j+1。

为了提高效率,可以使用前面介绍的通过lowbit来快速提取一个数中所有为1的位的方法进行优化。

当然也可以不使用那么高效的方法而是直接取出一个状态数的每一位。