算法笔记: DFS && BFS

这篇博客探讨了深度优先搜索(DFS)和广度优先搜索(BFS)在解决n件物品装包问题、序列A中选择平方和最大的子集以及迷宫路径寻找问题上的应用。通过递归实现的DFS和队列操作的BFS,展示了如何在限制条件下找到最优解。文章强调了不同搜索策略在时间和空间复杂度上的差异,并提供了实例代码进行解释。
摘要由CSDN通过智能技术生成

DFS

递归/栈

  • n件物品装包问题
void DFS(int index, int sumW, int sumC){
	 if(index == n){//已选物品个数
	 	if(sumW <= V && sumC > maxValue){
	 		maxValue = sumC;
	 		}
	 		return;
	 	}
	 	//岔道口
	 	DFS(index+1, sumW, sumC);
	 	DFS(index+1, sumW + w[index], sumC+c[index]);
	 }
int main(){
    DFS(0,0,0);
} 
  • 序列A中n个数选k个数使得和为x,选平方和最大的,注意 每个数只能选择一次
    (和第一个代码几乎一样
int n, k, x, maxSumSqu = -1, A[maxn];
vector<int> temp, ans;
void DFS(int index, int nowk, int sum, int sumSqu){
    if(nowk == k && sum == x){ //死胡同
        if(sumSqu > maxSumSqu){
            maxSumSqu = sumSqu; //更新
            ans = temp;
        }
        return;
    }
    if(index == n || nowk > k || sum > k) return;//返回
    temp.push_back(A[index]);
    DFS(index + 1, nowk +1, sum + A[index], sumSqu + A[index] * A[index]);
    temp.pop_back();
    DFS(index + 1, nowk, sum, sumSqu);
}

时间复杂度O( 2 n 2^n 2n
不是 n件物品全部确定后,而是背包容量不超过V 就更新最大值

void DFS(int index, int sumW, int sumC){
	 if(index == n){//已选物品个数
	 		return;
	 	}
	 	//岔道口
	 	DFS(index+1, sumW, sumC);//不选
	 	if(sumW + w[index] <= V){
	 		if(sumW + w[index] > ans){
	 			ans = sumW + w[index];
	 		}
	 		DFS(index+1, sumW + w[index], sumC+c[index]);
	 	}
	 }

BFS

  • BFS模板
void BFS(int s){
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        取队首元素top
        访问top
        将队首元素top出队
        将top下一层结点中未曾入队的结点全部入队,并设置为已入队
    }
}
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node{
    int x, y; //位置
    int step; //最小步数,层数
}S, T, Node;

int n, m;
char maze[maxn][maxn];
bool inq[maxn][maxn] = {false};
int X[4] = {0, 0, 1, -1};
int Y[4] = {1, -1, 0, 0};

//检查是否可以进入该位置
bool test(int x, int y){
    if(x >= n || x < 0 || y >= m || y <0) return false;
    if(maze[x][y] == '*') return false;
    if(inq[x][y] == true) return false;
    return true;//有效位置
}

int BFS(){
    queue<node> q;
    q.push(S);
    while(!q.empty()){
        node top = q.front();//取队首元素
        q.pop();
        if(top.x == T.x && top.y == T.y){ //判断是否到达终点
            return top.step;
        }
        for(int i=0;i<4;i++){
            int newX=top.x+X[i];
            int newY=top.y+Y[i];
            if(test(newX,newY)){
                Node.x=newX, Node.y=newY;
                Node.step=top.step+1;
                q.push(Node);
                inq[newX][newY]=true;
            }
        }
    }
    return -1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        getchar();//过滤掉每行后面的换行符
        for(int j=0;j<m;j++){
            maze[i][j]=getchar();
        }
        maze[i][m+1]='\0';
    }
    scanf("%d%d%d%d",&S.x,$S.y,&T.x,&T.y);
    S.step=0;
    printf("%d\n",BFS());
    return 0;
}

注意:inq的意思是 結点是否已入过队
STL的queue, 对队列元素的修改无法改变原元素,采用队列中存放元素的下标

q.push(i);
a[q.front()].data = 100;//a结构体
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值