枚举大小为k的子集
Posted autoint
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举大小为k的子集相关的知识,希望对你有一定的参考价值。
这种位操作不大可能分析出来,先看代码再分析。
代码
使用条件:(k>0)
void solve(int n,int k)
{
for(int comb = (1 << k) - 1; comb < (1 << n);)
{
// ...
int x = comb & -comb, y = comb + x;
comb = (((comb & ~y) / x ) >> 1) | y;
}
}
证明
[ egin{array}{} 首先是辅助变量x,yx ightarrow comb最低位y ightarrow comb的倒数第一段1取0,该1段前一个位置的0取1设上述y改变的部分为lencomb&sim y ightarrow len前取0,len中取1,len后取0(comb&sim y)/x ightarrow 长度为len的全1串((comb & sim y) / x ) >> 1 ightarrow 右移1位,len-1综上(((comb & sim y) / x ) >> 1) | y ightarrow 把comb的len的前一个位置的0取1,末尾添上len-1个1 end{array} ]
然后这就是不重不漏的枚举。
所以时间复杂度(Oleft(inom{n}{k}
ight))
以上是关于枚举大小为k的子集的主要内容,如果未能解决你的问题,请参考以下文章