子集生成和回溯法

 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 }

 

posted @ 2015-02-13 16:30  daydaycode  阅读(211)  评论(0编辑  收藏  举报