zoukankan      html  css  js  c++  java
  • 奇偶剪枝算法

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

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

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

    把矩阵看成如下形式: 
    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 }
    ---------------- 人们生成的最美好的岁月其实就是最痛苦的时候,只是事后回忆起来的时候才那么幸福。
  • 相关阅读:
    在Power BI报表和仪表板中显示刷新日期时间
    微软Power BI 每月功能更新系列——12月Power BI 新功能学习
    在Microsoft Power BI中创建地图的10种方法
    您应该将报表从Excel转换为Power BI的8个原因
    OBS录制全屏游戏的方法(超好录屏)
    关于Adobe Premiere Pro视音频不同步的解决方法
    Npcap:Nmap项目里一个为Windows而生的嗅探库 Npcap: Nmap Project's packet sniffing library for Windows
    关于被malloc分配内存的指针
    VS2017 高级使用方法
    Npcap环境配置(Winpcap后继者) pcap的一种
  • 原文地址:https://www.cnblogs.com/livelihao/p/5180266.html
Copyright © 2011-2022 走看看