【搜索】之深度优先搜索DFS的简单理解与例题

DFS

深度优先遍历(DFS)也叫深度优先搜索。它的定义是:不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。

深度优先搜索 也可以说是 递归 ,在代码的实现中主要是利用函数调用自己,那么学习 深度优先搜索 的主要前置知识就是手写 函数 ,属于非常简单且基础的一种可以成为算法的东西,而其时间复杂度通常不低,在一些题目中可以获得部分分,代码方面也好写,所以也可以在 对拍 时候使用。

举个题做例子:

超级书架

题目描述

Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了。现在,只有书架的顶上还留有一点空间。

所有N(1<=N<=20)N(1 <= N <= 20)N(1<=N<=20)头奶牛都有一个确定的身高Hi(1<=Hi<=1,000,000H_i(1 <= H_i <= 1,000,000Hi(1<=Hi<=1,000,000- 好高的奶牛>_<)。设所有奶牛身高的和为S。书架的高度为BBB,并且保证1<=B<=S1 <= B <= S1<=B<=S
为了够到比最高的那头奶牛还要高的书架顶,奶牛们不得不象演杂技一般,一头站在另一头的背上,叠成一座“奶牛塔”。当然,这个塔的高度,就是塔中所有奶牛的身高之和。

为了往书架顶上放东西,所有奶牛的身高和必须不小于书架的高度。

塔叠得越高便越不稳定,于是奶牛们希望找到一种方案,使得叠出的塔在高度不小于书架高度的情况下,高度尽可能小。你也可以猜到你的任务了:写一个程序,计算奶牛们叠成的塔在满足要求的情况下,最少要比书架高多少。

输入格式
111行: 222个用空格隔开的整数:NNNBBB2..N+12..N+12..N+1行: 第i+1i+1i+1行是111个整数:HiH_iHi

输出格式
111行: 输出111个非负整数,即奶牛们叠成的塔最少比书架高的高度_

样例数据

input

5
16
3
1
3
5
6

output

1

注释

输出说明:

我们选用奶牛1、3、4、5叠成塔,她们的总高度为3 + 3 + 5 + 6 = 17。任何方案都无法叠出高度为16的塔,于是答案为1。

数据规模与约定

时间限制:1s

空间限制:256MB

分析

这就需要搞个递归,在递归里枚举每头牛,分出两种情况:这头牛取还是不取。
在这里插入图片描述
这里的函数首先需要两个变量:第几头牛,高度。
编不下去了, 放代码

#include <bits/stdc++.h>
using namespace std;
int k , da = 999999 , ans , h , p;//用da来记录高于书架的最低高度
int a[10086];
void sj(int m,int n)
{
	if(n >= h && da > n) da = n;//如果高度高于书架且低于其他方法,更新da
	if(m > k) return;     //递归中很重要的一点就是找到边界,不然无限循环
	sj(m + 1 , n);          //这头牛不往上摞
	sj(m + 1 , n + a[m]);     //这头牛往上摞
}
int main()
{
	cin >> k >> h;
	for(int i = 1 ; i <= k ; i ++)
	{
		cin >> a[i];      //第i头牛的高度
	}
	sj(0 , 0);            //一开始的时候用了0头牛,高度为0
	cout << da - h;         //输出高度差
	return 0;
}

有时候如果输不出东西,要检查边界是否设置得当

注:

有人(也可能只有我)会怀疑,递归中的

void sj(int m,int n)

在其中多次使用,是否会相互干扰。

肯定不会啊!!!

在这里插入图片描述
看图说话。
可以理解为倒二叉树在这里插入图片描述
把最左的一个枝干砍掉们不会影响其他几根枝干。
而在returnreturnreturn后,会继续运行其他树杈。

在这里插入图片描述
就是这么一个进栈出栈的过程。


深度优先搜索 其实很有可能搜索到相同的情况,那么在一些题目中我们可以做一个 来作记录,这样的方法也可以被称为 记忆化搜索

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值