zoukankan      html  css  js  c++  java
  • 记忆化搜索

    记忆化搜索

    ​ 记忆化搜索,属于DP的分支,但是其实现更加简单,依靠于DFS,所以在一些方面更具优越性;

    前言

    ​ 记忆化可以作为DP难以实现时一个简易的方法(我知道你们都秒切DP,就我一个蒟蒻不会QWQ).

    ​ 讲的很浅显,但是不要D讲者;

    浅谈

    ​ 记忆化搜素,顾名思义,是通过储存一个状态的最优信息,减少DFS的搜索树;

    ​ 记忆化搜索的几个条件,状态可以储存,而且没有层次的限制(若是一层一层了话,BFS?)

    ​ 它具有几个DP所不具有的优点:

    ​ 1.状态更少;

    ​ 2.可以减枝;

    ​ 3.实现更加简单;

    ​ 但是似乎在状压DP中用的是最多的;

    ​ [NOIP2016]愤怒的小鸟

    就是让你定几个抛物线(过原点),去砸小猪,看最少用几个小鸟;

    ​ 思路显然,我们知道两点定一个抛物线,那么考虑直接枚举小猪,定抛物线,二进制记录已经打过的小猪即可,时间复杂度 (O(n^2 log n)) ;

    ​ 当然我们还可以优化,枚举两个小猪优化到定一个小猪枚举另一个小猪,时间复杂度 (O(n logn)) ;

    ​ [NOIP2017]逛公园

    ​ 思路即,先跑个最短路,然后跑个最短路DP即可;

    ​ 但是这里要判 0 环,有两种方法,拓扑和DFS,拓扑就很显然了,但是有许多人写炸;

    ​ DFS判环我们曾经在SPFA判负环中见过,做法高效;

    ​ 那么我们可以采用DFS记忆化搜索,储存两维状态 (f[x][k]) ,第一维表示在哪个点,第二维表示与最短路的差值;

    ​ 如果我们跑了正向最短路,那么我们就可以反向建边,跑DFS,用 (dis[y]-dis[x]+edge[i].w) 求出差值,储存状态即可,而0环的判断,只要记录每个点是否访问过,如果在一次访问过之后再次访问,即得到0环;

    话外题

    ​ 状态压缩是我们常用储存状态的方式,而DFS与状压的结合更加完美,其减枝之后甚至比正解状压DP更快一步.

    ​ [NOIP2017]宝藏

    (n) 个点和 (m) 条道路,我们可以选择一个点出发,开拓道路的代价是 (L*K) (L代表这条道路的长度,K代表从起点到这条道路起点所经过的点的数量)

    我们既然是搜索专题,怎么能想正解DP呢 ;

    ​ 我们可以暴力枚举起点,然后搜索道路,时间复杂度 (O( 玄学 )=O( 超时 )) ;

    ​ 考虑优化;

    ​ 1.我们可以在记录状态时用二进制维护

    ​ 2.贪心地从较小边搜索,这样可以较快的解出较优解去减枝;

    ​ 3.每次将一个点的边枚举完之后再去枚举下一个点;

    ​ 4.在同一点,记录枚举到哪条边,避免重复枚举;

    ​ 5.进行最优解减枝,类似于IDA*的做法,我们记录一个当前点之后的价值,加上当前价值,进行减枝,最直接的做法是直接记录所有没有探寻的点的最小出边,然后乘上当前点的K即可;

    ​ 这种减枝速度极快,甚至比正解还快上几分...

    经验

    ​ 有的时候,正解很难得到,我们可以选择搜索,进行合理化减枝(注意,不要减枝错误),也许你就AK了;

  • 相关阅读:
    Nginx学习总结(一)
    zabbix3.4.8配置自动发现主机并监控
    Windows server 2012/2016系统安装zabbix3.2客户端
    CentOS7.6系统安装zabbix3.4.8客户端
    一个小爬虫的整体解决方案
    如何通过一个立方体搭建一栋楼
    用Scrapy框架开发的一个爬虫项目
    寻找替代imagemin更好的插件
    原生和es6复杂数组去重的方法
    javascript关于对象或者数组深克隆的写法
  • 原文地址:https://www.cnblogs.com/waterflower/p/11842552.html
Copyright © 2011-2022 走看看