dfs-深度优先搜索(Depth-First-Search)

dfs-深度优先搜索(Depth-First-Search)

进入ACM实验室以来,这是老师传授给我们的第一个知识点。我认为,dfs就是遍历全部。可是我发现我完全不会,因为dfs并不是for循环遍历。dfs其实是一种回溯。回溯的概念,用一张图片来解释。

在这里插入图片描述
这是一株美丽的二叉树。

在这里插入图片描述
明白了这个思路,咱们就可以想出一种方法来遍历所有的最后的节点。
了解复杂度的肯定都知道。如果节点一多的话,直接遍历是不行的,所以我们发明了一种方法叫剪枝
在这里插入图片描述

现在进行AC时刻

举个栗子。就用最经典的暴力背包吧;

题目描述

有一个背包,容积是30,有三样东西价值和体积分别为45,16 25,15 25,15试问,采取怎样的方法才可以把可以装进背包的物品的价值提升到最大。
二话不说直接上代码

#include<bits/stdc++.h>
using namespace std;
int w[]= {16,15,15},v[]= {45,25,25};
int tempw,tempv,totv;
int maxn=0;
void dfs(int t)
{
 if(t==3) {
  if(tempv>maxn&&tempw<=30)
   maxn=tempv;
  return ;
 }
 tempw+=w[t];
 tempv+=v[t];
 totv-=v[t];
 if(tempw<=30&&tempv+totv>maxn)
  dfs(t+1);
 tempw-=w[t];
 tempv-=v[t];
// totv+=v[t];
// totv-=v[t];
 if(tempv+totv>maxn)
  dfs(t+1);
 totv+=v[t];
}
int main()
{
 for(int i=0; i<3; i++)
  totv+=v[i];
 dfs(0);
 cout<<maxn<<endl;
}

如果我没猜错,没学会dfs的人一定看的一脸懵逼。所以我把我理解步骤一点点的呈现出来。
首先得理解一下思路。
思路就是这个东西放还是不放。
所以代码走起

#include<bits/stdc++.h>
using namespace std;
int w[]= {16,15,15},v[]= {45,25,25};
int main()
{
dfs(0);\\直接访问第零层;
return 0}
#include<bits/stdc++.h>
using namespace std;
int w[]= {16,15,15},v[]= {45,25,25};int tempw,tempv;
int maxn=0;
dfs(int t){
if(t==3)//3的意思是你背包里的东西,也就是你的树的深度;因为有三个物体,你只有012这三层,
//等你读取第2层之后理所当然的走到了第3层,也就是判断层。

{
if(tempv>maxn&&tempw<=30)//处理maxn可交换条件
   maxn=tempv;
  return ;
}
}

int main()
{
dfs(0);\\直接访问第零层;
return 0}
#include<bits/stdc++.h>
using namespace std;
int w[]= {16,15,15},v[]= {45,25,25};
int tempw,tempv,totv;
int maxn=0;
dfs(int t)
{
 if(t==3)
 {
  if(tempv>maxn&&tempw<=30)
   maxn=tempv;
  return ;
 }//此时我就想往背包里填东西了,现在就说判断这个东西放不放的时候到了
 //放
 tempw+=w[t];
 tempv+=v[t];
 totv-=v[t];
 if(tempw<=30&&tempv+totv>maxn)//同时想到如果你把所有的东西都放进去
 //都不如你最大的价值大那么这个东西就不用放了;
 //(因此引用totv,一开始就是全部的总价值,每一次丢弃都会把总价值改变)
  dfs(t+1);//现在就是放了,放了的后续还有很多,留给以后;
  //如果你不想放你后悔了,你是不是得拿出来呢?
   tempw-=w[t];
 tempv-=v[t];
totv+=v[t];//这样就拿出来了
//然后就说这个东西我不放的情况
totv-=v[t];
 if(tempv+totv>maxn)
  dfs(t+1);
 totv+=v[t];//因为你只是试试,并不是真的就放了,所以你得放进去再拿回来。
}
int main()
{

 dfs(0)return 0;
}
#include<bits/stdc++.h>
using namespace std;
int w[]= {16,15,15},v[]= {45,25,25};
int tempw,tempv,totv;
int maxn=0;
void dfs(int t)
{
 if(t==3) {
  if(tempv>maxn&&tempw<=30)
   maxn=tempv;
  return ;
 }
 tempw+=w[t];
 tempv+=v[t];
 totv-=v[t];
 if(tempw<=30&&tempv+totv>maxn)
  dfs(t+1);
 tempw-=w[t];
 tempv-=v[t];
// totv+=v[t];你会发现一放一拿正好抵消了,所以就可以不写,但是为了理解还是写了
// totv-=v[t];
 if(tempv+totv>maxn)
  dfs(t+1);
 totv+=v[t];
}
int main()
{
 for(int i=0; i<3; i++)
  totv+=v[i];
 dfs(0);
 cout<<maxn<<endl;
}

最终这个暴力背包就解决了。

跑一下程序
在这里插入图片描述这个暴力背包整理OVER!
鸣谢Mr.Zhang
By-轮月

发布了32 篇原创文章 · 获赞 12 · 访问量 1204

猜你喜欢

转载自blog.csdn.net/qq_35339563/article/details/103226234