7.3子集生成
2017-02-08 18:06
113 查看
给定一个集合,枚举所有可能的子集,本节讨论的集合中没有重复元素
7.3.1 增量构造法
第一种思路一次选出一个元素放到集合中
#include<stdio.h>
#include<cstring>
using namespace std;
int A[100];
void print_subset(int n,int* A,int cur){
for(int i=0;i<cur;i++)
printf("%d ",A[i]);
printf("\n");
int s=cur?A[cur-1]+1:0;
for(int i=s;i<n;i++){
A[cur]=i;
print_subset(n,A,cur+1);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(A,0,sizeof A);
print_subset(n,A,0);
}
return 0;
}
上面的代码用到了定序的技巧:规定集合A中所有元素的编号从小到大排列
7.3.2 位向量法
构造一个位向量B[i],而不是直接构造子集A本身,其中B[i]=1,当且仅当i在子集A中
#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int* B,int cur){
if(cur==n){
for(int i=0;i<cur;i++)
if(B[i])
printf("%d ",i);
printf("\n");
return;
}
B[cur]=1; //选第cur个元素
print_subset(n,B,cur+1);
B[cur]=0;
print_subset(n,B,cur+1);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(B,0,sizeof B);
print_subset(n,B,0);
}
return 0;
}
7.3.3 二进制法
为了处理方便,最右边的位总是对应元素0,而不是元素1
#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int s){
for(int i=0;i<n;i++)
if(s&(1<<i)) printf("%d ",i);
printf("\n");
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<(1<<n);i++)
print_subset(n,i);
}
return 0;
}
7.3.1 增量构造法
第一种思路一次选出一个元素放到集合中
#include<stdio.h>
#include<cstring>
using namespace std;
int A[100];
void print_subset(int n,int* A,int cur){
for(int i=0;i<cur;i++)
printf("%d ",A[i]);
printf("\n");
int s=cur?A[cur-1]+1:0;
for(int i=s;i<n;i++){
A[cur]=i;
print_subset(n,A,cur+1);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(A,0,sizeof A);
print_subset(n,A,0);
}
return 0;
}
上面的代码用到了定序的技巧:规定集合A中所有元素的编号从小到大排列
7.3.2 位向量法
构造一个位向量B[i],而不是直接构造子集A本身,其中B[i]=1,当且仅当i在子集A中
#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int* B,int cur){
if(cur==n){
for(int i=0;i<cur;i++)
if(B[i])
printf("%d ",i);
printf("\n");
return;
}
B[cur]=1; //选第cur个元素
print_subset(n,B,cur+1);
B[cur]=0;
print_subset(n,B,cur+1);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(B,0,sizeof B);
print_subset(n,B,0);
}
return 0;
}
7.3.3 二进制法
为了处理方便,最右边的位总是对应元素0,而不是元素1
#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int s){
for(int i=0;i<n;i++)
if(s&(1<<i)) printf("%d ",i);
printf("\n");
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<(1<<n);i++)
print_subset(n,i);
}
return 0;
}
相关文章推荐
- 《算法竞赛入门经典》-7.3-子集生成
- 算法竞赛入门经典读书笔记(四)7.3子集生成
- 【算法竞赛入门经典】7.3子集生成【增量构造法】【位向量法】【二进制法】
- 读《算法竞赛入门经典》 7.3子集生成
- 算法竞赛入门经典读书笔记(四)7.3子集生成
- 《算法竞赛入门经典》-【第七章:暴力求解法】-7.3:子集生成
- 7.3 子集生成
- 算法:子集生成
- 子集生成
- 子集生成的三种方法
- 子集生成
- 非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
- 子集生成模板、
- 关于算法竞赛入门经典一书的思考学习——枚举排序和子集生成!
- GVIM 7.3设置不生成备份文件
- 生成一个集合的所有子集 Subset
- 子集生成算法——增量构造法
- 生成子集以及置换
- 枚举 子集生成
- ACMjava子集生成的三种方法,增量构造,辅助位向量,二进制法