• 2018暑假集训专题小结 Part5


    目录

    基础搜索算法 (Basic search algorithm)
    复杂度玄学算法 (Uncertainty of Time Complexity)
    正确性玄学算法 (Uncertainty of Correctness)

    基础搜索算法

    前言:此类算法一般是用来水部分分的。或者就是用来辅助一些算法。或者就是巧妙地利用题目性质做题,总之,很好用。

    百度优先搜索
    上百度找题解,可以解决大部分题目。

    深度优先搜索
    就是对于一个搜索路径,一直深入搜索下去,直到不能为止。

    迭代加深搜索
    就是在深搜的基础上加上一个深度限制,比如搜索深度到200就停止。
    时间复杂度与深搜差不多。

    折半搜索
    把搜索的限制变成原来的一半。
    比如n=16,我们搜索8个,然后后面的就边搜索边用hash来判断重复(是否有答案)。

    宽度优先搜索
    用队列实现,每个节点所展开的节点存到队列里,层层递进,搜索优先度与到起点的距离有关。

    双向宽搜
    对于一个起点状态与终点状态,两边同时宽搜(终点的拓展方法相反)。然后就时时刻刻用hash来判断是否相交。
    时间复杂度:
    单向:k^d(d为深度,k为每次拓展的状态的个数)
    双向:sqrt(k^d)

    例题:
    T0:八数码
    注,此题可以用各种方法做。

    T1:[CQOI2013]新数独
    给定一个空数独,现在要往其内填数字满足:
    每行都是 1, … , 9 的排列
    每列都是 1, … , 9 的排列
    每个 3 × 3 的子矩阵都是 1, … , 9 的排列
    每个 3 × 3 的子矩阵中相邻的两格要满足规定的大小关系

    题解:
    深搜直接填数,然后加剪枝。当然,优先剪掉第4个条件不符的,这样子更快。

    T2:No name
    给定数集合S,从中选出6个数a,b,c,d,e,f
    求是否满足(a*b+c)/d-e=f
    |S|<=100

    题解:我们化化式子——
    a*b+c=f*d+e*d
    然后我们折半搜索,搜3个数,然后再搜剩下的3个数。加加剪枝即可。
    时间复杂度O(|S|^3)

    T3:平衡的子集(JZOJ 4841)
    N个数中选出若干个数,分成两部分使得两部分的数的和相同。求方案。
    N<=20;a[i]<=10000000000;

    题解:折半搜索
    每次搜索10个数,有3种状态—— -1(选到第一组),0(不选),1(选到第二组)

    T4:[SDOI2011]打地鼠
    有一个n*m的地图,每个点上有若干个地鼠。
    你可以用一个大小为R*C的锤子打地鼠,每次会把一个大小为R*C区域内的每个点的地鼠个数减一,要求每次打的区域中每个点上都至少有一个地鼠。
    你可以随意设置R,C,问最终最少打多少次。
    n,m<=100,每个点的地鼠个数<=100000

    题解:
    直接枚举锤子的大小,然后判断大小是不是总数的约数。
    判断可不可以砸就直接从左上角开始依次往后,能砸就砸。

    复杂度玄学算法

    前言:此类题的时间复杂度都很难证明或是有一个十分准确的值,一般就是O(能够)这种时间复杂度。要用到很多巧妙的方法去做,卡卡时间。当然,要看你非洲还是欧洲啦。

    A*
    A*主要在于一个估价函数,设为h(s),其中s是个状态。
    令f(s)=g(s)+h(s)
    其中g(s)表示从起点到当前状态的代价。
    搜索时按照f(s)从小到大搜索。

    可以说是赋予计算机一个智慧。

    一个经典的比方——
    这里写图片描述
    从a走到b。
    我们的估价函数就可以设为:
    a与b的|横坐标差|+|竖坐标差|
    当然,g(s)=a到当前状态s所在的位置走的路程。

    然后,就可以按照f(s)来进行搜索。

    具体的估价函数如何弄——
    考虑对运行的效率和正确性有什么影响。
    令h*(x)表示x到终点的最小代价。
    当h(x) < h*(x)的时候会使得答案错误。
    h(x)与h*(x)越接近,效率越高。

    注意该问题即可。

    IDA*
    这个就是迭代加深版的A*。
    加上最优性剪枝即可优化很多。

    例题:
    T0:八数码。
    不多说。

    T1:No name
    给出n个点,m条边,要求从1到n的k短路。
    n<=1000

    题解:
    A*做:
    每次寻找f(x)最小的转移。
    那么我们发现,从1出发,第K次到达n时就找到了第k短路。
    估价函数就是:当前状态的点到终点的最短路。

    T2:The Morning after Halloween
    w×h的网格上有n小写字母(代表鬼)。要求把他们分别移动到相应的大写字母里。每步可以有多个鬼同时移动,但每步结束后不能有两个鬼在同一格,也不能在一步之内交换位置。
    w,h≤16;n≤3
    数据保证所有空格连通,所有障碍也连通。
    且任意2×2的子网格中必然有一个障碍。
    Time Limit: 6s

    这里写图片描述这里写图片描述
    上面有四种走法。

    题解:
    解1:bfs。但是直接不行,因为状态数可能达到256^3
    优化一:压缩状态,将每一个位置转换成[0,255]的整数来表示。
    优化二:数据保证每个2×2的子网格至少有一个障碍,因此很多位置可转移的新位置是有限的。我们可以预处理每一个位置能转移到的新位置,从而降低转移的复杂度。
    优化三:优化判重方法。最多只有3个鬼,所以可以用一个三维数组记录。
    优化四:双向。

    解2:A*。很显然可以做,但是我们看看如何设估价函数。
    和K短路的思路类似,每次我们扩展一个估价最小的点。
    关于h(n)估价函数的选取,大致有一下两种:
    1.比较当前状态与目标状态有多少个点在正确位置上。
    2.各点到目标位置的最大曼哈顿距离。
    这是最常见的两种估价函数。这题显然应该是第二种。

    正确性玄学算法

    前言:水分、碾正解的利器。

    爬山算法
    简单的贪心。比如当前一个人要下山,那么他就每次选择一个比当前更低的地方走过去,否则就原地不动。
    然而,很容易陷入坑中。

    模拟退火
    物理学知识用在信息学上面。
    喜闻乐见。
    根据分子热力学,在温度为T的时候:
    p(dE)=exp(dE/(kT))
    k是一个常数,dE为出现能量差的概率。
    那么我们可以发现,温度会随着时间的变化去变化。

    那些其实都不需要去管。
    模拟退火其实就是另外的一种贪心,基于爬山算法。
    形象比喻:我们就每次下山的时候,一开始活力充沛,就会有心情继续上山。但到后来,可能没精力了,那么渐渐地,心情不允许我们向上爬了。
    也就是我们有一定几率会接受比当前劣一点的状态,但逐渐到后来,就不会有那么高的几率接受了。

    这样往往可以以特别高的几率走到最优解。

    这里写图片描述

    遗传算法
    生物学知识用在信息学上。
    我还不会。

    例题:
    T1:费马点
    一个图上有n个点,找一个点使这个点到其他点距离最短。

    题解:模拟退火。
    我们一开始有一个几率,在一个相对于中心的点(自己找)。然后我们就每次随机走一段一定的距离,最后就可以走到最优的答案。

    T2:[HDU 5017] Ellipsoid
    给定一个椭球,要求在上面找到一个点离原点最近。

    题解:模拟退火。
    与上题很像。

    T3:[BZOJ 3680]吊打XXX
    PTY又AK了。众人非常不爽,决定吊打PTY。
    PTY将自己分身成n个,于是众人吊打n个PTY,方式如下:
    用绳子把n个PTY吊起来,穿过天花板上一个坐标为(xi,yi)的孔,然后在上面绑在一起。
    众人发现每个PTY的重量不一样,所以最终在的位置不是正中心。
    问最终绑的那个绳结会到哪个位置。
    n<=10000,-100000<=xi,yi<=100000

    简单题意:一个圆盘,中间有一些线串过,线上方全部打了个结,下方有不同重量的球挂着。求这个结最终会到什么位置。

    题解:模拟退火,我们每次同样地移动。
    但是如何判断优与劣呢?
    由于我们要使合力为0,那么我们就可以把不同的洞到结的距离依次记录,然后一个力可以分解成两个力。那么我们可以看做是坐标轴,那么我们就有4个力。分别计算即可。

    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    mahout协同过滤算法
    如何实现团队的自组织管理
    Trail: JDBC(TM) Database Access(3)
    JavaEE5 Tutorial_JavaBean,JSTL
    JavaEE5 Tutorial_Jsp,EL
    JavaEE5 Tutorial_Servlet
    J2SE7规范_2013.2_类
    J2SE7规范_2013.2_类型_命名
    Trail: JDBC(TM) Database Access(2)
    Trail: JDBC(TM) Database Access(1)
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148401.html
Copyright © 2020-2023  润新知