• 奇偶剪枝算法


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

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

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

    把矩阵看成如下形式: 
    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,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 }
    ---------------- 人们生成的最美好的岁月其实就是最痛苦的时候,只是事后回忆起来的时候才那么幸福。
  • 相关阅读:
    win10 安装python教程
    nginx http请求无法加载https的css样式
    (第二十天)[js] 写一个验证身份证号的方法
    Linux重启nginx
    (第十一天)[js] 返回到顶部的方法有哪些?把其中一个方法出来
    看了一篇闭包的,推荐一下~
    HTTP状态码
    (第十天)[js] 写一个获取当前url查询字符串中的参数的方法
    (第九天)[js] 写一个判断数据类型的方法
    (第八天)[js] 写一个加密字符串的方法
  • 原文地址:https://www.cnblogs.com/livelihao/p/5180266.html
Copyright © 2020-2023  润新知