搜索
本校的Lazer2001 学长为我们讲了搜索(乱搞)
- 搜索
- 基础:位运算
- 超级基础
- 感觉有点难度?
- bitset
- 例题:位运算 & bitset
- 基础搜索
- DFS
- BFS
- 特殊的搜索方式
- 双向DFS搜索
- 双向BFS搜索
- 哈希
- 康托展开
- 迭代加深搜索(IDDFS)
- 例题:埃及分数
- 解答
- 启发式搜索(A∗A∗A^{*})
- 估价函数
- 例题:斗地主
- 总结(垃圾话)
- 基础:位运算
基础:位运算
(对于二进制数 X X )
超级基础
判断第位是否为1:X&(1<<(i-1))
将第 i i 位赋值为1:X|(1<<(i-1))
将第位赋值为0:X&(X^(1<<(i-1)))
将第 i i 位取反:X^(1<<(i-1))
感觉有点难度?
将最后一个1变成0:X-lowbit(X)=X-X&(-X)
统计1的个数:while(X) {X-=lowbit(X); num++; }
枚举子集:for(s=X;s;s=(s-1)&X)
(复杂度)
bitset
其实不会
总结如下:
利用位运算压缩过的bool数组
可以对两个bitset进行正常的与、或、非、左移右移等位运算
还有一些方便的操作:any,none,count,flip
空间、时间效率都有较大提升
其实就是把很多个bool->几个long long的操作了。
例题:位运算 & bitset
- 给定 n n 个数,求它们所有子集和的异或和。
- n皇后问题 n⩽15 n ⩽ 15
基础搜索
DFS
BFS
Lazer2001 前辈的神奇代码。
特殊的搜索方式
各种乱搞
双向DFS搜索
考虑一个问题的解空间为 xy x y 规模级别,每个解可有两段结果并起来,即可考虑利用双向DFS搜索。
常用于统计类搜索问题。
双向BFS搜索
考虑一个问题的解空间为 xy x y 规模级别,每个解可有两段结果并起来,即可考虑利用双向BFS搜索。(就是复制的)
常用于最优化搜索问题。
哈希
康托展开
迭代加深搜索(IDDFS)
有限度的乱搞
例题:埃及分数
将一个分数 ab a b 表示成多个单位分数(不能相同)的和,要求用的分数个数尽量少,个数相同时最小的分数尽量大。 1<a<b<500 1 < a < b < 500
解答
每次限制使用的分数数量
利用深度上限进行剪枝:之后的分数都严格比当前小,如果在规定步数内按照当前分数的大小都无法达到要求,则剪枝。
启发式搜索( A∗ A ∗ )
估价函数
决定了“搜索的顺序”
需要满足什么条件?
f(n)=g(n)+h(n) f ( n ) = g ( n ) + h ( n )
h(n)⩽r(n) h ( n ) ⩽ r ( n ) ,其中 h(n) h ( n ) 为估价函数, r(n) r ( n ) 为实际代价
A∗ A ∗ 算法
只要找到解,则一定是最优解
BFS、dijistra都是(没有任何优化的) A∗ A ∗ 算法
例题:斗地主
NOIP原题(UOJ(随机数据)/洛谷(加强版))
预处理: n⩽7 n ⩽ 7 时,用HASH表(或map)直接存答案
不搜索单张,贪心打小牌。
堪称搜索神题
总结(垃圾话)
Lazer2001学长因为在SCOI2018上被电子神大卡没了了100+,(张叔叔博客)但他仍然是一位优秀的老师。他的随和给我们留下了深刻的印象。
他用了一晚上告诉我们他的经验教训,拳拳真情,令我等不禁见贤思齐(见不贤内自省)。
希望他在今后的奋斗路上,长风破浪,步步高升!