搜索专题练习
前言:
学科被包菜一学期。滚回机房了。结果。。。上午模拟考果不其然地爆0了。。。想了三个小时所谓“正解”,结果四个正解都是搜索?啊啊啊啊啊啊啊啊啊放弃治疗QAQ。
慢慢来吧。搜索其实今年NOIP之前也想练过,但是自己只是刷了一些巨水无比的搜索题,有点难度的其实看题解都不是很懂。自己欠的账。跪着也得还啊。
这个专题可能会持续很久,慢慢咕着
模拟赛九道搜索?/哭晕
1.[HNOI2013]比赛
大意:一场球赛,给定每队得分,求出满足规则的比赛过程方案数。
一个重要的思想是,由于求的是方案数,因此我们其实并不关心每场比赛具体的输赢。
另外,我们可以通过所有队的总分数,算出所有比赛中到底有几场平局。
所以搜索的方向就很明显了(个人理解):枚举每一场比赛,将胜利或平局的分数“分配”给其中某支队伍,统计合法方案的数量。
关于优化:
1.玄学排序:
因为我们不关心具体输赢嘛,所以分数为3 2 1和1 2 3其实没什么区别 口胡数据 。因此我们就。玄学排序?按照从大到小的顺序搜索。很多搜索好像都可以排序优化复杂度。搜索树规模缩小了很多。(sto gql 60分 dalao)
1.可行性剪枝:
枚举到某一个队伍,如果它剩下的比赛都赢了还达不到目标分数,显然是不行的。
2.记忆化搜索:
记忆化这个东西。。。其实作用挺大的。本题中因为状态很少,所以可以考虑记忆化。使用Hash表储存当前状态方案总数。在搜完一个队伍的得分后,查询剩余队伍的分数集合的方案数,如果有就可以直接用,没有就递归存进去。 这东西感觉很强,虽然现在自己也比较懵逼,但以后要多练
2.智慧珠游戏
大意:游戏由三角形盘件和 12 个形态各异的零件组成,零件可以翻折旋转。给定几个初始零件,求精确覆盖盘件的方案
这题。。。
dalao评价:普及思想,NOI代码量。
十二种零件翻折旋转就有56种方案呃,先预处理个几百行然后零剪枝暴搜吧。。。
会Dancing Link的神仙就当我没说
3.方格
大意:一个 n*m 的方格。一些格子上已经被涂上了 k 种颜色中的任意一种。把剩下所有为染色的格子全部染上 k 种颜色中的一种。使得涂完后,从方格的左上角到右下角不存在一条有两个相同颜色格子的路径,并且路径只能向下或向右走。求一共有多少种染色方法能够满足以上的条件?
先咕着。剪枝多而且不是很好想。看别人代码没看懂QAQ。
3.[HAOI2008]移动玩具
大意:给定两个4×4的01矩阵,相邻两个格子可以交换。求从初始矩阵到目标矩阵需要操作的次数。
水题。。。
不过我还是十分信仰地讲一下我的非正解!/滑稽
就是两个不相邻格子一定是可以交换并不影响其他格子的 (不会证明)。所需要的操作次数就是这两个格子的曼哈顿距离 (依然不会证明) 。
这时候只需要对比两个矩阵,找出需要交换的格子。然后每次BFS,找到离它最近并且需要交换的格子,互换并记录对答案贡献就好啦。
为什么说是非正解呢,因为局部最优解不一定是全局最优解。。。 (这就是说这题水的原因,这个解法洛谷100考试也有90分) 。然后!重点来了!我们使用阿姆斯特朗回旋涡轮加速喷气式 搜索,从四个方向分别搜一遍(随机化搜索就更好了),然后取最优答案。结果自测卡成100分。。。
至于正解。。。不重要。(好吧其实是双向广搜+状态压缩记忆化,但我懒得打了)
4.乌龟棋
这题现在看真心不难了。以前做的时候还纠结了好一会。。。
就是四维DP大力转移呃。记搜也可以。不讲了。
5.CF-177-A
(CF比较卡就不上链接了)
满足以下条件的字符串:
包含恰好 k 个不同字符
长度为 n
相邻两个字符不同 • 如果存在多个,请输出字典序最小的
• 如果不存在,请输出-1
这题不是红果果的构造题吗。为什么要用搜索。
可是考试的时候这题没人A。。。
n=k=1的时候没特判 ,-10;
k=1,n>1的时候没输出-1;这个。。。考试的时候竟然题面没这句话?嗯,是出题人的锅
6.虫食算
是很好的题目了!对搜索各种细节的处理和剪枝方面都有很好的锻炼。
关于优化:
1.三个字符串的长度都是n,由此可以想到一个最简单的剪枝:最高位不能有进位
2.如果对于第位,既不满足,也不满足,
则剪枝。
3.搜索顺序问题:从低位开始搜效率更高。
比较经典的题目,就不赘述了。
7.单词矩阵
还不是很会。。。
先给一个学长的题解。敲这里
咕咕。
8.CF-54-E
大意:给定一个(可能)不成立的等式:a+b=c ,要求插入尽量少的数字使得这个等式成立
先咕为敬。
T7 最大团
所以这题同样是好题呃→meet in the middle(双向搜索)
1.将图取反,就变成了求最大独立集
2.把所有点分成两个集合,记作A、B
3.对A预处理出它的所有子集的最大独立集,记录下来
如何预处理:这里可以用dp做一下,对子集T中的任意一点v,不选就是从dp[T-v]转移来,选就是从dp[T-v-u]转移来(u是所有和v有连边的点)。
这个过程中可以顺便记个方案数
然后对于B我们枚举独立集,把A中独立集中,和B中独立集有边相连的点都删了,答案就是剩余的点
P.S.一个比较好的优化是,类比邻接矩阵,但矩阵的每一行我们都用一个二进制数存起来。再结合位运算,查询的时候就可以O(1)地处理掉。
反正我没打过状压
啊啊啊啊啊啊不想写了这几天摆的太多一直没写QAQ。
我。一定。慢慢。填坑。