深度优先搜索(DFS)
一、定义
搜索是计算机程序设计中一种最基本、最常用的算法。搜索算法是直接基于计算机高速运算的特点而使用的计算机求解方法。它是从问题的初始状态出发,根据其中的约束条件,按照一定的策略,有序推进,不断深入,对于达到的所有目标状态(解空间),一一验证,找到符合条件的解(可行解),或者找出所有可行解中的最优解按照推进的控制策略,搜索一般分为宽度优先搜索和深度优先搜索。
二、深度优先搜索
深度优先搜索是将当前状态按照一定的规则顺序,先拓展一步得到一个新状态,再对这个新状态递归拓展下去。如果无法拓展,则退回一步到上一个状态,再按照原先设定的规则顺序重新寻找一个状态拓展。如此搜索,直至找到目标状态,或者遍历完所有状态。所以,深度优先搜索也是一种“盲目”搜索。
![](https://i-blog.csdnimg.cn/blog_migrate/e3e369f3303b88b1f67ed25b219ffdda.png#pic_center)
三、算法框架
深度优先搜索(Depth First search,DFS),简称深搜,其状态“退回一步”的顺序符合“后进先出”的特点,所以采用“栈”存储状态。深搜适用于要求所有解方案的题深搜可以采用直接递归的方法实现,其算法框架如下:
void dfs(int dep, 参数表) {
自定义参数;
if(当前是目标状态)
作出解或者作计数、评价处理;
else {
for(int i = 1;i <= 状态的拓展可能数; i++) {
if(第i种状态拓展可行) {
维护自定义参数;
dfs(dep+1,参数表);
}
}
}
}
四、经典题目
体积
题目:
给出 n 件物品,每件物品有一个体积 V i ,求从中取出若干件物品能够组成的不同的体积和有多少种可能。至少选择1件物品。
分析:
此题用深搜解决,在搜索时传入两个参数,表示当前判断到的编号,与体积总和,出口为当判断到第n+1号时,如果当前总和只有一个,就答案+1,最后输出答案-1。
代码:
#include <cstdio>
bool flag[1005];
int a[1005], ans, n;
void dfs(int dep, int sum) {
if (dep == n + 1) {
if (!flag[sum]) {
ans++;
flag[sum] = true;
}
return;
}
dfs(dep + 1, sum + a[dep]);
dfs(dep + 1, sum);
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
dfs(0, 1);
printf("%d", ans - 1);
return 0;
}