深度优先搜索dfs剪枝例题讲解

本文通过两个实例详细讲解了深度优先搜索(DFS)在解决实际问题中的应用,包括如何使用DFS解决引爆地图上所有炸弹的最少操作数问题,以及在生日蛋糕问题中找到最小表面积的蛋糕制作方案。文章强调了剪枝技巧的重要性,通过行、列标记避免重复搜索,以及在蛋糕问题中通过体积预处理和最优性剪枝优化搜索过程。
摘要由CSDN通过智能技术生成

引爆炸弹
在一个 n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

在这里插入图片描述

现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
数据范围:1≤n,m≤1000;

这问题其实与连通块类似。
我们把可以互相引爆的炸弹放到同一个集合中,那么最后划分的集合个数就是我们要求的答案。显然,引爆集合中任意一个炸弹造成的效果都一样,我们可以遍历nm的方格中所有炸弹,如果当前炸弹之前没被引爆,就引爆它,即标记他所在集合中的所有炸弹。
可以用DFS搜出一个炸弹所在的集合,每次引爆一个炸弹后,就搜它所在的行列是否有其他炸弹,然后继续搜索。因为每次炸弹最多有n
m个,每个炸弹引爆后要检查所在行和列都有没有炸弹,时间复杂度是O(nm(n+m))
这里有一个剪枝,每行每列最多搜一遍,于是可以标记一下搜过的行列避免重复搜索,这样每个格子都最多被检查两边,时间复杂度为O(nm)

row和col分别表示每行、列是否考虑过引爆。
boom函数,首先标记当前炸弹已经被引爆。如果当前行没有被引爆,就应该循环判断该行是否有没有引爆的炸弹并引爆。
如果当前列没有引爆过,那就引爆当前列并标记,然后循环判断该列是否有没有引爆的炸弹,有就继续搜索。
在main函数里,我们要统计答案,只要遍历n*m的方格,每遇到一个没引爆的炸弹,答案就增加1,并调用boom函数引爆所有相关联的炸弹。
示例代码:

#include <stdio.h>
#include <iostream>
using namespace std;
char mat[1010][1010];
int n, m;
bool row[1010],col[1010];
void boom(int x,int y){
   
    mat[x][y]=0;
    if(!row[x]){
   
        row[x]=true;
        for(int i=0;i<m;i++){
   
            if(mat[x][i]=='1'){
   
                boom(x,i);
            }
        }
    }
    if(!col[y]){
   
        col[y]=true;
        for(int i=0;i<n;i++){
   
            if(mat[i][y]=='1'){
   
                boom(i,y);
            }
        }
    }
}
int main() {
   
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
   
        scanf("%s", mat[i]);
    }
    int cnt=0;
    for(int i=0;i<n;i++){
   
        for(int j=0;j<m;j++){
   
            if(mat[i][j]=='1'){
   
                cnt++; 
                boom(i,j);
            }
        }
    }
    cout<<cnt<<endl;
    return 0;
}

生日蛋糕
今天是花椰妹的生日,蒜头君打算制作一个体积为 nπ 的 m 层生日蛋糕送给她。蛋糕每层都是一个圆柱体,设从下往上数第 i(0≤i<m)层蛋糕是半径为 R[i] , 高度为H[i]的圆柱。当 i>0 时,要求R[i]<R[i-1]且H[i]<H[i-1]
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 Q 最小。令iQ=Sπ,请编程对给出的 n 和 m,找出蛋糕的制作方案(适当的 R[i]和H[i] 的值),使 S 最小。(除 Q 外,以上所有数据皆为正整数)

为了方便叙述,本体表面积和体积是除以pai以后的结果,且表面积是指除去下底面后的表面积。
整个蛋糕的体积 n = ∑ i = 0 m − 1 R i 2 H i n=\sum_{i=0}^{m-1}R_i^2H_i n=i=0m1Ri2Hi
表面积 s = R 0 2 + 2 ∑ i = 0 m − 1 R i H i s=R_0^2+2\sum_{i=0}^{m-1}R_iH_i s=R

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值