dfs和回溯

本文探讨了在解决背包问题、顺次数和括号生成等难题时,如何利用DFS和回溯策略。DFS作为一种遍历方法,尤其适用于理解二叉树和图问题。回溯则是DFS的一种带有剪枝操作的形式,能在某些情况下比动态规划更快找到解。文章提供了回溯的通用模板,并分析了回溯在01背包问题中可能导致超时的原因,强调理解回溯算法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多问题动态规划比较难想,dfs就可以用来兜底,再加上合适的剪枝就成了回溯,有时候可能比dp更快,dfs感觉比递归更好理解,一般都可以使用二叉树或者图的方式来理解。一般用回溯能解的一定能用dfs解因为dfs是遍历了所有的解。回溯遍历的解是dfs的子集

 

目录

01背包问题

dfs求解

回溯求解

1291. 顺次数

22. 括号生成


01背包问题

dfs求解

题目来源:https://www.acwing.com/problem/content/2/



#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
//dfs 显然超时
int w[MAXN];    // 重量 
int v[MAXN];    // 价值 
int f[MAXN];  // f[i][j], j重量下前i个物品的最大价值 

int maxprofit = 0;
void dfs(int w[],int v[],int i,int tmpw,int tmpv,int n,int m){
    if(i==n){ //终止条件
        if(tmpv > maxprofit && tmpw <= m){
            maxprofit = tmpv;
        }
        return ;//无论如何这里都要出去
    }
    if(tmpw > m){ //对不合理的解进行剪枝
        return ;
    }
    dfs(w,v,i+1,tmpw,tmpv,n,m);//不取第i件物品
    dfs(w,v,i+1,tmpw+w[i],tmpv+v[i],n,m);//取第i件物品
}
int main() 
{
    int n, m;   
    cin >> n >> m;
    for(int i = 0; i < n; ++i) 
        cin >> w[i] >> v[i];
    dfs(w,v,0,0,0,n,m);
    cout<<maxprofit<<endl;
    
    return 0;
}

不用修改的变量都可以放到dfs的外面


#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;


//超时


int w[MAXN];    // 重量 
int v[MAXN];    // 价值 

int n,m;
int maxprofit = 0;
void dfs(int i,int tmpw,int tmpv){
    if(i==n){
        if(tmpv > maxprofit && tmpw <= m){
            maxprofit = tmpv;
        }
        return ;
    }
    if(tmpw > m){
        return ;
    }
    
    dfs(i+1,tmpw,tmpv);
    if(tmpw + w[i] <=m)
    dfs(i+1,tmpw+w[i],tmpv+v[i]);
}
int main() 
{
       
    cin >> n >> m;
    for(int i = 0; i < n; ++i) 
        cin >> w[i] >> v[i];
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值