二进制枚举模版
模拟写法
枚举子集
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int b[100];
cin>>n;
for(int i=0; i<=n; i++)b[i]=0;
while(b[0]==0){
for(int i=1; i<=n; i++)cout<<b[i];
cout<<"\n";
int j=n;
while(b[j]==1)
j--;
b[j]++;
for(int i=j+1; i<=n; i++)b[i]=0;
}
return 0;
}
组合输出
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, r;
int b[100];
cin>>n>>r;
for(int i=1; i<=n; i++)b[i]=i;
b[0]=-1;
while(b[0]==-1){
for(int i=1; i<=r; i++)cout<<b[i]<<" ";
cout<<"\n";
int j=r;
while(b[j]==n-r+j)j--;
b[j]++;
for(int i=j+1; i<=r; i++)b[i]=b[i-1]+1;
}
return 0;
}
位运算写法
枚举子集
#include<bits/stdc++.h>
using namespace std;
int a[10];
void print_subset(int n)
{
for(int i=0; i<(1<<n); i++){
for(int j=0; j<n; j++)
if(i&(1<<j))
cout<<a[j]<<" ";
cout<<endl;
}
}
int main()
{
int n;
cin>>n;
for(int i=0; i<n; i++)a[i]=i+1;//初始化数组
print_subset(n);
return 0;
}
组合输出
#include<bits/stdc++.h>
using namespace std;
int a[10];
void print_subset(int n, int m)
{
for(int i=0; i<(1<<n); i++){
int num=0, kk=i;//num统计i中1的个数;kk用来处理i
while(kk){
kk=kk&(kk-1);//清除kk中的最后一个1
num++;//统计1的个数
}
if(num==m){//二进制数中的1有k个,符合条件
for(int j=0; j<n; j++)
if(i&(1<<j))
cout<<a[j]<<" ";
cout<<endl;
}
}
}
int main()
{
int n, m;
cin>>n>>m;
for(int i=0; i<n; i++)a[i]=i+1;//初始化数组
print_subset(n, m);
return 0;
}
除了以上写法还可以使用dfs写法
时间复杂度均为指数级别,使用于数据规模在20左右的暴力枚举