搜索
1.搜索
1.定义:搜索,也就是对状态空间进行枚举,通过穷尽所有的可能来找到最优解,或者统计合法解的个数。
搜索有很多优化方式,如减小状态空间,更改搜索顺序,剪枝等。
搜索是一些高级算法的基础。在 OI 中,纯粹的搜索往往也是得到部分分的手段,但可以通过纯粹的搜索拿到满分的题目非常少。
2.DFS
1.例题:
例题1
把正整数n分解为3个不同的正整数,如6=1+2+3,排在后面的数必须大于等于前面的数,输
出所有方案。
正常方法:
for (int i = 1; i <= n; ++i)
for (int j = i; j <= n; ++j)
for (int k = j; k <= n; ++k)
if (i + j + k == n) printf("%d = %d + %d + %d\n", n, i, j, k);
3.递归实现枚举
1.例题链接:
https://www.acwing.com/problem/content/94/
2.解法:
首先我们先要明白这个题会得出来多少对
很简单,他就是n^2
但是我们需要把所有的方案都求出来并且输出出来
所以可以采取dfs递归的方式
3.函数:
4.原理:
实际上我们可以把每一个数看作一个点,每一对答案就可以在这个递归搜索树中形成一条路径,进而求出路径数
5.注意:
注意看函数的最后一行,这个步骤非常重要,如果不还原现场的话,就会和原来一样,所以一定要写一下这个东西
6.进阶:
如果我们换成这样呢
https://www.acwing.com/problem/content/95/
7.进阶解法:
但是这种方法会比较浪费时间
所以可以这样:
4.真正的DFS
1.例题:
https://www.acwing.com/problem/content/167/
2.解法
设计状态,我们考虑到需要求的是最少多少量缆车,那我们可以考虑表示为dfs(now,cnt),现在已经用了cnt辆车,正在装第now只猫,在第i辆缆车中已经装有cab[i]只猫
那么对于每一只猫,有两种选择,第一种是单独再放一个缆车,还有一种就是装在之前已经租过的缆车中,搜索得到的解中求最大值就可以
3.实现方案
画红框的部分是在比较每个缆车能不能装下