1,状态,转移与枚举
什么是状态?什么是转移?什么是枚举?
状态
状态就是在搜索递归期间所需寻求答案的几个变量(这概念有点难懂,看到下面自然就懂了)。
比如说如下代码:
void dfs(int x, int step){
if(step == 114514){
return ;
}
dfs(x + 1, step + 1);
}
在上面代码,状态是 x 和 step(其实看状态是什么变量就看函数所使用了哪些变量),如果还是没有懂,可以去问问度娘。
转移
转移就是对不同情况而对状态进行更改,在上面代码中,它的状态转移为:
当 step 不为 114514 时,(x + 1, step + 1),当 step 为 114514 时,退出递归。
枚举
枚举就是在通过不断调用函数(递归)来查找答案,可以理解为广义的枚举。
另外,在分析时,不要忘了时间复杂度和空间复杂度。
2,相关数据结构
在学习广搜之前,必须要学会这个数据结构:队列
队列(FIFO,全名First In First Out,先进先出),想学习队列的可以看看其他的文章,我之后也会出一个关于队列的博客,大家可以关注一下,这里就不多说了。
3,例题练习
注:例题如果简单将不会展示代码
状态
用 (x, step) 表示走到 x 楼按了 step 次按钮。
(a, 0) 是初始状态,目标状态 (b, min(step))。
转移
上下楼梯,转移到 (x + num[x], step + 1) 或 (x - sum[x], step + 1) 。
空间复杂度
空间复杂度:O(n^2)。
时间复杂度
时间复杂度:O(2n^2)。
状态
(x, sum) 表示用 x 张邮票构成面值 sum。
转移
每次选取一张邮票,转移到 (x + 1, sum + a[i])。
空间复杂度
状态空间复杂度:O(k * k * max(a[i])。
时间复杂度
每个状态转移时间复杂度:O(n),总时间复杂度为:O(k^2 * n * max(a[i]))。
4,最后bb几句
总的来说,我觉得还是深搜好一点(仅个人感觉),但是在绝大情况下,广搜的时间复杂度会比深搜的时间复杂度少一点,所以怕 T 的可以使用BFS。