奇偶剪枝算法

剪枝是什么,简单的说就是把不可行的一些情况剪掉,例如走迷宫时运用回溯法,遇到死胡同时回溯,造成程序运行时间长。

剪枝的概念,其实就跟走迷宫避开死胡同差不多。若我们把搜索的过程看成是对一棵树的遍历,那么剪枝顾名思义,就是将树中的一些“死胡同”,不能到达我们需要的解的枝条“剪”掉,以减少搜索的时间。

剪枝种类较多,说一下奇偶剪枝

把矩阵看成如下形式: 
0 1 0 1 0 1 
1 0 1 0 1 0 
0 1 0 1 0 1 
1 0 1 0 1 0 
0 1 0 1 0 1 
从为 0 的格子走一步,必然走向为 1 的格子 。
从为 1 的格子走一步,必然走向为 0 的格子 。
即: 
从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。

所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!

 例题:HDU 1010

http://acm.hdu.edu.cn/showproblem.php?pid=1010

 

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 using namespace std;
 5 char mat[6][6];
 6 bool flg,visit[6][6];
 7 const int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
 8 int n,m,t,xnum,sx,sy,ex,ey;
 9 void dfs(int x, int y, int step) {
10     if(flg) return;
11     if(step == t && x == ex && y == ey) {
12         flg=true;
13         return;
14     }
15     if(step >= t) return;
16     int dis = abs((double)x-ex) + abs((double)y-ey);
17     dis = t-dis-step;
18     if(dis<0 || dis%2) return;//奇偶剪枝
19     for( int i=0; i<4; ++i) {
20         int tx = x+dir[i][0];
21         int ty = y+dir[i][1];
22         int tstep = step+1;
23         if(tx>=0 &&tx<n &&ty>=0 &&ty<m &&!visit[tx][ty] &&mat[tx][ty] != 'X') {
24             visit[tx][ty] = true;
25             dfs(tx,ty,tstep);
26             visit[tx][ty] = false;//回溯
27         }
28     }
29     return;
30 }
31 
32 int main() {
33     freopen("C:\\CODE\\in.txt", "r", stdin);
34     while(~scanf("%d%d%d",&n,&m,&t)&&n+m+t) {
35         //printf("n=%d m=%d t=%d\n",n,m,t);
36 
37         xnum = 0;
38         flg = false;
39         for( int i=0; i<n; ++i) {
40             getchar();
41             for( int j=0; j<m; ++j) {
42                 visit[i][j]=false;
43                 scanf("%c",&mat[i][j]);
44                 if('S' == mat[i][j]) {
45                     sx=i;
46                     sy=j;
47                     visit[i][j]=true;
48                 } else if('D' == mat[i][j]) {
49                     ex=i;
50                     ey=j;
51                 } else if('X' == mat[i][j]) {
52                     ++xnum;
53                 }
54             }
55         }
56         getchar();
57 
58         if(n*m-xnum > t)
59             dfs(sx,sy,0);
60         if(flg)
61             puts("YES");
62         else
63             puts("NO");
64     }
65     fclose(stdin);
66     return 0;
67 }

 

posted @ 2016-02-05 15:19  闪耀子  阅读(820)  评论(1编辑  收藏  举报