枚举排列(手写)
(以下是枚举可重数组里的排列
(枚举1~n的话,自己写
void print_permutation(int n, int* p, int* a, int cur) {
if(cur == n) {
for(int i = 0; i < n; i++) cout<<a[i]<<" ";
printf("
");
return ;
}
for(int i = 0; i < n; i++) if((vis[p[i]]<cnt[p[i]]) && (!i || p[i]!=p[i-1])) {
a[cur] = p[i]; vis[p[i]]++;
print_permutation(n, p, a, cur+1);
vis[p[i]]--;
}
}
注意!p数组(即原数组)需要经过排序!! (不相信请输出{1 2 1})
枚举排列(stl大法好)
sort(p, p+n);
do{
...do what you want to do;
}while(next_permutation(p, p+n));
也要排序..
也能解决可重元素的排列
不解释
子集生成(二进制法)
以下为集合{0,1,2...n-1}的子集枚举方法
(如果是其他集合,也可以用这种方法,只不过把它看成下标而已
输出子集s对应的各个元素
void print_subset(int n. int s) {//打印{0,1,2...n-1}的子集s
for(int i = 0; i < n; i++)
if(s & (1<<i)) printf("%d ", i);
printf("
");
}
枚举子集
for(int i = 0; i < (1<<n); i++) //枚举各个子集对应的编码0,1,2...2的n次-1
print_subset(n,i);
枚举比x大的最小数,比x小的最大数
#include <cstdio>
#include <algorithm>
int n, X, ans;
int a[111];
int main() {
scanf("%d", &n);//n: a1 a2 a3 a4 。。
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
scanf("%d", &X);
for(int i = 0; i < (1 << n); i++) {//最大值 == 2的n - 1 次方
int tmp = 0;
for(int j = 1; j <= n; j++) {
if(i & (1 << j - 1)) {//当这个式子 != 0 时 说明 找到
tmp += a[j];
}
// if((i >> j - 1) & 1)
}
if(tmp == X) ans++;
}
printf("%d
", ans);
return 0;
}