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

DFS

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

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

举个题做例子:

超级书架

题目描述

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

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

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

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

输入格式
1 1 1行: 2 2 2个用空格隔开的整数: N N N B B B 2.. N + 1 2..N+1 2..N+1行: 第 i + 1 i+1 i+1行是 1 1 1个整数: H i H_i Hi

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

样例数据

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)

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

肯定不会啊!!!

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

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


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

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值