预备知识:
一个元素数量为n的集合的子集个数是2^n.
证明:有n个元素,每个元素进行一次判断要不要把它选出来加进子集里,这样判断n次,产生了2^n种不同结果。
搜索的顺序:
从前往后遍历1~n,依次判断每个数是选还是不选。
找到一个就输出一个的代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n; 4 int st[20]; //标记每一位有没有被选,0表示还没考虑,1表示选,2表示不选 5 void dfs(int u) { //u表示当前在判断第几位 6 if (u == n + 1) { //如果已经判断完了 7 for (int i = 1; i <= n; i++) { 8 if (st[i] == 1) { 9 cout << i << " "; 10 } 11 } 12 cout << endl; 13 return; 14 } 15 //不选u 16 st[u] = 2; 17 dfs(u + 1); 18 st[u] = 0; //回溯恢复现场 19 //选u 20 st[u] = 1; 21 dfs(u + 1); 22 st[u] = 0; //回溯恢复现场 23 } 24 int main() { 25 cin >> n; 26 dfs(1); //从下标为0开始搜索 27 return 0; 28 }
把答案存下来最后输出的代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n; 4 int st[20]; //标记每一位有没有被选,0表示还没考虑,1表示选,2表示不选 5 int ways[1 << 15][16]; //最多2^15种方案,每种方案15个数 6 int cnt; //cnt表示当前方案的数量 7 void dfs(int u) { //u表示当前在判断第几位 8 if (u == n + 1) { //如果已经判断完了 9 for (int i = 1; i <= n; i++) { //记录方案 10 if (st[i] == 1) { 11 ways[cnt][i] = i; 12 } 13 } 14 cnt++; 15 return; 16 } 17 //不选u 18 st[u] = 2; 19 dfs(u + 1); 20 st[u] = 0; //回溯恢复现场 21 //选u 22 st[u] = 1; 23 dfs(u + 1); 24 st[u] = 0; //回溯恢复现场 25 } 26 int main() { 27 cin >> n; 28 dfs(1); //从下标为0开始搜索 29 for (int i = 0; i < cnt; i++) { 30 for (int j = 1; j <= n; j++) { 31 if (ways[i][j]) { 32 cout << ways[i][j] << " "; 33 } 34 } 35 cout << endl; 36 } 37 return 0; 38 }