题意:

       有一个城镇,是4*4的大小的,然后你控制一块云彩,2*2的,你每天可以有9种走的方法,上下左右,或者不动,走的时候可以走1或者2步,云彩所在的地方肯定会下雨,然后给你做多365天的安排,要求某些日子的某些城镇不能下雨(因为有**节日),还有任何地方都不能有连续超过6天不下雨。

思路:

       首先9种走法,做多连续六点不下雨,这个可以直接DFS深搜,(BFS不知道行不行,没试过,主要担心的是内存,反正目测BFS队列QUEUE占用的内存太大),如果不优化的话的话时间复杂度可是9^365根本受不了啊,然后就是考虑优化,也就是mark走过的状态,关键是怎么标记这个状态,一开始我是想找16个素数,然后根据每个格子的步数去计算每个16个步数得到的一个特别值去hash状态,可以失败了,找素数的方法不行,举个例子 3 * 7 + 7 * 3 = 7 * 3 + 3 * 7,然后就是考虑状态压缩,可是按照最笨的放发的话状态压缩的9^16中状态,后来我自己优化了下,还是9^12种状态,还是不行,后来看了别人的解释,一开始有疑惑,想了好久才说服自己,说下标程,可以只考虑四个点,假如当前用云彩的左上角表示云彩,那么我们只要考虑的四个点就是
1 1 ,1 3 ,3 1,3 3也就是云彩在四个角落的时候的坐标,判断下雨天数的时候可以只判断这四个,还有mark的时候也是mark[t][n][a][b][c][d] t 天数,a云彩当前位置(只记录左上角,离散化之后就9个),a b c d分别是当前那4个关键位置连续没下雨的天数,然后就直接DFS就行了,下面解释下为什么这样是对的:

(1)充分性 : 只要这四个点都满足天数不大于7 那么全图肯定都满足,这个自己看下就知道了,因为把图分成四块,这四个关键点肯定是每一个块中连续不下雨天数最长的。

(2)必要性 : 如果全图都满足连续不下雨情况,那么这四个关键点必然满足,因为要想让(1 ,1) ,(1 ,4) ,(4 ,1) ,(4 ,4)都满足,那么必须走这4个关键点,别的点照顾不到这。

(3)还有就是只用这四个点代表唯一性是否正确,这个我犹豫了好久,就是这个地方一开始怎么也想不明白,现在说下我目前的理解。

假如当前状态

1111 2222        1111 2222   如果按照上面的那个方法mark必须证明这两个状态是一

1111 2222        1111 2222   个状态,我的理解是四个关键位置的连续不下雨天数一定

3333 4444        3332 4443   比自己所在的模块的所有天数都大,无论什么时候,那么

3333 4444        3332 4443   也就是说如果以后出现问题肯定是这四个最大的中的某个

                             出现问题,也就是别的点永远都只是陪衬,所以 陪衬的点

                             怎么样不会影响总的状态以及最终的趋势,所以这种mark                               的方法是正确的,这个是我自己的理解。

#include<stdio.h>

#include<string.h>

int DAY[367];

bool mark[366][10][8][8][8][8];

int ys[12] = {0 ,1 ,2 ,3 ,0 ,4 ,5 ,6 ,0 ,7 ,8 ,9};

int dir[9][2] = {0 ,0 ,0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0 ,0 ,2 ,0 ,-2 ,2 ,0 ,-2 ,0};

int OK ,T;

bool ok(int t ,int x ,int y ,int a[])

{

    int aa = (x - 1) * 4 + y;

    int bb= (x - 1 + 1) * 4 + y;

    int cc = (x - 1) * 4 + y + 1;

    int dd = (x - 1 + 1) * 4 + y + 1;

    if(x < 1 || x > 3 || y < 1 || y > 3)

    return 0;

    if(a[1] >= 7 || a[2] >= 7 || a[3] >= 7 || a[4] >= 7)

    return 0;

    if(((1 << aa) & DAY[t]) || ((1 << bb) & DAY[t]) || ((1 << cc) & DAY[t]) || ((1 << dd) & DAY[t]))

    return 0;

    if(mark[t][ys[aa]][a[1]][a[2]][a[3]][a[4]]) return 0;

    return 1;

}

void DFS(int t ,int x ,int y ,int a[])

{

    if(t == T) OK = 1;

    if(OK) return ;

    int b[5];

    for(int i = 0 ;i < 9 ;i ++)

    {

        if(t == 0 && i) break;

        int nowt = t + 1;

        int nowx = x + dir[i][0];

        int nowy = y + dir[i][1];

        for(int j = 1 ;j <= 4 ;j ++)

        b[j] = a[j] + 1;

        if(nowx == 1 && nowy == 1) b[1] = 0;

        if(nowx == 1 && nowy == 3) b[2] = 0;

        if(nowx == 3 && nowy == 1) b[3] = 0;

        if(nowx == 3 && nowy == 3) b[4] = 0;

        if(ok(nowt ,nowx ,nowy ,b))

        {

            mark[nowt][ys[(nowx-1)*4+nowy]][b[1]][b[2]][b[3]][b[4]] = 1;

            DFS(nowt ,nowx ,nowy ,b);

        }

    }

    return ;

}

int main ()

{

    int i ,j;

    while(~scanf("%d" ,&T) && T)

    {

        memset(DAY ,0 ,sizeof(DAY));

        for(i = 1 ;i <= T ;i ++)

        {

            int tmp;

            for(j = 1 ;j <= 16 ;j ++)

            {

                scanf("%d" ,&tmp);

                DAY[i] = DAY[i] | (tmp << j);

            }

        }

        memset(mark ,0 ,sizeof(mark));

        OK = 0;

        int a[5];

        a[1] = a[2] = a[3] = a[4] = 0;

        DFS(0 ,2 ,2 ,a);

        printf("%d\n" ,OK);

    }

    return 0;

}

POJ2044 深搜+剪枝(云彩下雨)的更多相关文章

  1. Hdu3812-Sea Sky(深搜+剪枝)

    Sea and Sky are the most favorite things of iSea, even when he was a small child.  Suzi once wrote: ...

  2. poj1190 生日蛋糕(深搜+剪枝)

    题目链接:poj1190 生日蛋糕 解题思路: 深搜,枚举:每一层可能的高度和半径 确定搜索范围:底层蛋糕的最大可能半径和最大可能高度 搜索顺序:从底层往上搭蛋糕,在同一层尝试时,半径和高度都是从大到 ...

  3. UVA 10160 Servicing Stations(深搜 + 剪枝)

    Problem D: Servicing stations A company offers personal computers for sale in N towns (3 <= N < ...

  4. ACM 海贼王之伟大航路(深搜剪枝)

    "我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...

  5. hdu 1518 Square(深搜+剪枝)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! ...

  6. POJ-1724 深搜剪枝

    这道题目如果数据很小的话.我们通过这个dfs就可以完成深搜: void dfs(int s) { if (s==N) { minLen=min(minLen,totalLen); return ; } ...

  7. 一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>

    题目传送 显然是道深搜题.由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积. 找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]. 可 ...

  8. 模拟赛T5 : domino ——深搜+剪枝+位运算优化

    这道题涉及的知识点有点多... 所以还是比较有意思的. domino 描述 迈克生日那天收到一张 N*N 的表格(1 ≤ N ≤ 2000),每个格子里有一个非 负整数(整数范围 0~1000),迈克 ...

  9. HDU 1175 连连看 (深搜+剪枝)

    题目链接 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以 ...

随机推荐

  1. rest framework ViewSet

    ViewSets 路由选择确定要用于一个请求哪个控制器之后,控制器负责做出请求的感并产生相应的输出. - Ruby on Rails的文档 Django的REST框架允许你的逻辑一组在一个类中的相关意 ...

  2. Azure Front Door(二)对后端 VM 进行负载均衡

    一,引言 上一篇我们讲到通过 Azure Front Door 为我们的 Azure App Service 提供流量转发,而整个 Azure Front Door 在添加后端池的时候可选的后端类型是 ...

  3. python之对象与类

    1.类的定义 类是一个用户定义类型,类似与c语言中的结构体 class <ClassName>: "类的帮助信息"#类文档字符串 class_suite #类体 其中C ...

  4. lms框架即将发布第一个版本了

    lms微服务框架介绍 LMS框架旨在帮助开发者在.net平台下,通过简单的配置和代码即可快速的使用微服务进行开发. LMS通过.net框架的主机托管应用,内部通过dotnetty/SpanNetty实 ...

  5. Hystrix 实战经验分享

    一.背景 Hystrix是Netlifx开源的一款容错框架,防雪崩利器,具备服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能. 尽管说Hystrix官方已不再维护,且有A ...

  6. vue 项目集成 husky+commitlint+stylelint

    最近刚换了新工作,这两天也没有业务上的需求,做了一些前端工程化方面的东西.要在现有的项目中集成 husky+commitlint+stylelint,也不能对现有代码产生影响. 使用 lint 的目的 ...

  7. 微信小程序 | app.json配置属性

    app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. widows: 用于设置小程序的状态栏.导航条.标题.窗口背景色. navig ...

  8. 使用 Velero 跨云平台迁移集群资源到 TKE

    概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...

  9. 18. vue-router案例-tabBar导航

    目标: 做一个导航tabbar 一. 分析 我们的目标是做一个导航tabbar, 要求 这个导航不仅可以在一个页面使用, 可以在多个页面通用 每个页面的样式可能不一样 每个页面的图标, 文字可能不一样 ...

  10. 宝塔linux7.4.2/windows6.8 的版本中的安全随笔

    在2020/8.23宝塔官方发布了一条关于宝塔linux7.4.2和Windows6.8版本中存在的重大的安全隐患 通知来源https://www.bt.cn/bbs/thread-54644-1-1 ...