子集生成和回溯法
1 //子集生成,增量构造法 2 3 void print_subset(int n,int *a,int cur) 4 { 5 for(int i=0;i<cur;i++) 6 cout<<a[i]; 7 cout<<endl; 8 int s=cur?a[cur-1]+1:0; 9 for(int i=s;i<n;i++) 10 { 11 a[cur]=i; 12 print_subset(n,a,cur+1); 13 14 } 15 } 16 //子集生成,位向量法 17 void print_subset(int n,int *b,int cur) 18 { 19 20 if(cur==n) 21 { 22 23 for(int i=0;i<cur;i++) 24 { 25 if(b[i]) 26 cout<<i; 27 } 28 cout<<endl; 29 } 30 b[cur]=1; 31 print_subset(n,b,cur+1); 32 b[cur]=0; 33 print_subset(n,b,cur+1); 34 } 35 36 //八皇后问题 37 38 void search(int cur) 39 { 40 if(cur==n) 41 tot++; 42 else 43 { 44 for(int i=0;i<n;i++) //第cur行放皇后在i列 45 { 46 c[cur]=i; 47 int ok=1; 48 for(int j=0;j<cur&&ok;j++) //怎样可以在O(1)时间内判断? 尝试用vis数组标记法 49 { 50 if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j]) 51 ok=0; 52 } 53 if(ok) 54 { 55 search(cur+1); 56 } 57 } 58 } 59 } 60 61 //八皇后改进 62 int n,tot; 63 int vis[3][MS*2]; 64 int c[MS]; 65 66 void search(int cur) 67 { 68 if(cur==n) 69 tot++; 70 else 71 { 72 for(int i=0;i<n;i++) 73 { 74 if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]) //cur-i<0,都加 n 即可 75 { 76 c[cur]=i; 77 vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1; 78 search(cur+1); 79 vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; 80 } 81 } 82 } 83 }