二进制枚举子集

目录

什么是二进制枚举子集

得到整数X

幼儿园买玩具

islands打炉石传说


什么是二进制枚举子集

对于n个数,我们用n位二进制数来表示每个数的状态(选/不选),1代表选,0代表不选。

由数学知识可知,此时一共有2^n种情况,即 1 << n 种情况

而这 2^n 种情况就对应着这 n 个数所选取组成的集合的数量。即n个数组成的集合的子集数量。

假设有5个数,那么5位二进制数为:xxxxx。

假设:11001,这就表示由第1、第4、第5个数组成的一个子集。

那么同样,对于一个长度为n的数组,想要求它的所有子集,就可以从 0 遍历到 2^n - 1,其中每个数由二进制表示,就对应该数组中的部分元素。

那么如何判定 nums数组中的某一个数 是否在列举出来的某一个子集里面呢?

假设当前列举出来的子集为:41 = 0101001。

可以看出来,第1、4、6个数在该子集中,那么如何通过计算进行判断呢?

判断第4个数在其中:

对于 位运算: 1 << 3 = 0001000,此时 (0101001) & (0001000)  ≠ 0 ,此时就代表第4个数在该子集中。

即:假设当前子集的二进制表示对应十进制数 number,判断第 x 个数是否在当前子集中,就用 number & ( 1 << (x-1) ),若结果不为0,则第x个数存在于该子集中

注意,这里第x数,如果从1开始数,那么后面就是 1 << (x-1)。如果从0开始数,就是 1 << x。具体问题具体分析。

接下来是一些例题。

得到整数X

描述

小明有 n个互不相同的正整数,现在他要从这 n个正整数之中无重复地选取任意个数,并仅通过加法凑出整数 X。求小明有多少种不同的方案来凑出整数 X。

输入

第一行,输入两个整数 n,X(1≤n≤20,1≤X≤2000)。
接下来输入 n个整数,每个整数不超过 100。

输出

输出一个整数,表示能凑出X的方案数。

用例输入:

6 6

1 2 3 4 5 6

用例输出:

你可能感兴趣的:(算法,算法,数据结构)