深度优先搜索实战(1)---小猫爬山

在开始之前,我们要先了解深度优先搜索的基本知识。

DFS(深度优先搜索)能解决哪些问题?

一般来说,DFS用于暴搜,连通性问题,求解符合条件的方案数,最大值,最小值等问题。

DFS的要素

一般来说,DFS具有下列要素:

1,终止条件。所有的递归类解法都有一条递归边界,也就是我们这里的终止条件。

2,减枝。什么叫减枝呢?我们知道很多时候,我们在递归的时候,由于条件限制比较少,数据分布比较不合理等问题,导致我们往往会进行大量无意义的计算。比如我们在输出数组中最大值的时候,我们倘若事先知道该数组是由从大到小排列的话,我们只需要直接输出数组的最后一位就可以了,并不需要依次遍历。而减枝类似,我们优先遍历分支较少的节点,或者当我们达到某一个条件的时候,我们放弃遍历下面的节点,这就是减枝的操作。

3,递归搜索下一层。

4,保护现场和恢复现场。这里的作用是让我们能够重复访问该节点,且保证节点的数据内容不变。

小猫下山问题

我们来看题干:

本题要求最少要多少辆车,符合我们深度优先搜索能解决问题的范畴。我们开始解题,首先我们要确定深度优先搜索函数的每个节点的参数。很显然,我们每个节点的参数是当前所用的车辆数和当前处理的猫猫数。

那么,我们的终止条件就是,当我们的猫猫数等于n的时候,输出当前的车辆数,该车辆数就是我们的答案。我们设置变量ans来记录我们的答案。我们赋值变量ans的初始值的时候要赋值大一些,这样我们才能往下求其最小值。题目要求最少的车辆数,那么也就是说,一旦我们的车辆数大于当前ans的时候,我们便可以放弃求接下来的节点,直接return即可。

我们坐车的情况有两种,也就是我们有两种情况可进入下一节点。第一种情况,我们当前的车可以容纳下一只猫猫,那么我们就进入下一节点,为猫猫数加1,车不变。第二种情况,我们当前的车不能容纳下一只猫猫,那么我们就要把那只猫猫单独放到一个车子里,再新买一个车,下一节点为车加1,猫猫也加1。

接下来看代码实现:

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int catw[20],carw[20];
int ans=20;  
int n,w;
void dfs(int cat,int car){
    if(car>=ans){//减枝
        return;//检验
    }
    if(cat==n){
        ans=car;
        return;
    }
    for(int i=0;i<car;i++){
        if(carw[i]+catw[cat]<=w){
            carw[i]+=catw[cat];
            dfs(cat+1,car);
            carw[i]-=catw[cat];
        }
    } 
    carw[car]=catw[cat];
    dfs(cat+1,car+1);
    carw[car]=0;
}
int main(){
    cin>>n>>w;
    for(int i=0;i<n;i++){
        cin>>catw[i];
    }
    sort(catw,catw+n);//减枝
    reverse(catw,catw+n);//胖猫优先上车
    dfs(0,0);
    cout<<ans<<endl;
    return 0;
}

注意这里的胖猫优先,我们先把我们的数据处理一下,按猫重量的从大到小排列,优先处理胖猫,因为胖猫的选择分支较少,优先处理能减少系统的计算时间。

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值