• 深度优先搜索DFS,求解部分和问题及poj2386水洼问题


    深度优先搜索(DFS)是搜索的手段之一。它从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直至找到最终的解。

    部分和问题:

    给定整数a1、a2、...、an,判断是否可以从中选出若干数,使它们的和恰好为k。

    分析:

    从a1开始按顺序决定每个数加或不加,在全部n个数都决定后再判断它们的和是不是k即可。因为状态数是2n+1(每个数都有加和不加两种情况),所以复杂度是O(2n)。

    代码如下:

    /*
    题目描述:能否找到数组a中的元素相加之和等于指定的数k
    解决方法:深度优先搜索(dfs)对每个元素组合进行遍历 
    */
    #include<iostream>
    using namespace std;
    int a[100],k,n;
    
    //已经从前i项得到了和sum,然后对于i项之后的进行分支 
    bool dfs(int i,int sum){
        //如果前n项都计算过了,则返回sum是否与k相等 
        if(i==n) return sum == k;
        //不加上a[i]的情况 
        if(dfs(i+1,sum)) return true;
        //加上a[i]的情况 
        if(dfs(i+1,sum+a[i])) return true;
        //加不加a[i],都被无法与k相等,则返回false 
        return false;
    } 
    
    int main(){
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        cin>>k;
        if(dfs(0,0)){
            cout<<"Yes"<<endl;
        }else{
            cout<<"No"<<endl;
        }
        return 0;
    } 

     部分和问题是DFS的基本题,现在我们稍微深入,求解poj2386,水洼问题

    题目描述:

    给定一个矩阵(m*n),其中W表示有水,. 表示干地,现给出定义在W周围(包括该W)的8个坐标位置(上下左右,左上左下右上右下)有W存在则形成水洼(水洼具有传递性),求这个矩阵中有多少个水洼?

    样例输入:

    10 12
    W........WW.
    .WWW.....WWW
    ....WW...WW.
    .........WW.
    .........W..
    ..W......W..
    .W.W.....WW.
    W.W.W.....W.
    .W.W......W.
    ..W.......W.

    样例输出:

    3

    分析:可从任一个W开始,判定周围是否存在W,进行深搜,并将遍历到的W都改为.,那么最后进行深搜的次数便是水洼的个数。

    #include<iostream>
    #include<cstring>
    using namespace std;
    int m,n;
    char pool[101][101];//题中矩阵 
    
    void dfs(int x,int y){
        //首先将其改为干地 
        pool[x][y]='.';
        //对每个方向进行遍历 
        for(int i=-1;i<=1;i++){
            for(int j=-1;j<=1;j++){
                int nx=x+i,ny=y+j;
                //若为'W',则沿着继续搜索 
                if(nx>=0&&ny>=0&&nx<m&&ny<n&&pool[nx][ny]=='W'){
                    dfs(nx,ny);
                }
            }
        }
    } 
    
    int find(){
        int count = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                //遍历整个矩阵,若为'W',启动深搜,并计数 
                if(pool[i][j]=='W'){
                    dfs(i,j);
                    count++;
                }
            }
        }
        return count;
    }
    
    int main(){
        cin>>m>>n;
        for(int i=0;i<m;i++){
            cin>>pool[i];
        }
        cout<<find()<<endl;
        return 0;
    }
  • 相关阅读:
    Stack堆栈的数据结构
    反坦克导弹相关网页
    Java 执行jar文件出现版本错误信息
    Python3 数字保留后几位
    Python3: Windows系统上同时安装Python2和Python3
    Linux 搭建FTP
    DBCP、c3p0、Druid三大连接池区别
    Sybase 存储过程中IF的用法
    Confluence5.8部分空间名称显示为问号的解决方案
    Mysql 更改编码方式
  • 原文地址:https://www.cnblogs.com/tz346125264/p/7704921.html
Copyright © 2020-2023  润新知