DFS之剪枝与优化——AcWing 165. 小猫爬山

DFS之剪枝与优化

定义

DFS之剪枝与优化指的是在执行深度优先搜索(DFS, Depth-First Search)时,采取的一系列策略来减少搜索空间,避免无效计算,从而加速找到问题的解。剪枝是指在搜索过程中,当遇到某些条件不符合解的要求或者可以预判后续搜索不会产生有效解时,直接放弃这条搜索路径,这一过程称为剪枝。优化则是指通过调整搜索策略、顺序等,提高搜索效率。

运用情况

  1. 组合优化问题:如全排列、组合总和、子集问题等,剪枝可以避免生成无效解。
  2. 图的遍历与搜索:在寻找特定路径或计算连通分量时,剪枝可以减少搜索范围。
  3. 游戏AI:如棋类游戏中预测对手可能的走法,剪枝减少计算量。
  4. 约束满足问题:如数独、任务调度等,剪枝帮助快速排除不满足条件的解。

注意事项

  1. 剪枝条件的选择:剪枝条件应严格且准确,避免误剪有效解。
  2. 搜索顺序:合理安排搜索顺序,优先探索最有希望的分支。
  3. 状态重置:回溯时确保正确恢复现场,避免状态污染。
  4. 记忆化:对于重复子问题,使用记忆化技术存储中间结果,避免重复计算。
  5. 资源管理:注意栈或递归深度限制,防止栈溢出。

解题思路

  1. 明确剪枝条件:分析问题特性,确定何时可以安全地剪枝。
  2. 优化搜索顺序
    • 分支较少优先:优先探索分支较少的路径,减少搜索深度。
    • 启发式排序:依据某种评估函数排序待探索节点,优先探索最有潜力的节点。
  3. 可行性剪枝:在探索前,如果可以证明当前路径无法导致有效解,立即剪枝。
  4. 最优性剪枝:在某些最优化问题中,如果已知当前路径不能优于已找到的最佳解,剪枝。
  5. 迭代加深DFS:结合深度限制,逐步增加深度限制进行搜索,适用于寻找最短路径等问题。
  6. 记忆化搜索:在适用场景下,利用动态规划思想存储中间结果,避免重复计算。

AcWing 165. 小猫爬山

题目描述

165. 小猫爬山 - AcWing题库

运行代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;int n, m;
int w[N];
int sum[N];
int ans = N;void dfs(int u, int k)
{if(k >= ans) return;if(u == n){ans = k;return;}for(int i = 0; i < k; i ++ )if(sum[i] + w[u] <= m){sum[i] += w[u];dfs(u + 1, k);sum[i] -= w[u];}sum[k] = w[u];dfs(u + 1, k + 1);sum[k] = 0;
}int main()
{cin >> n >> m;for(int i = 0; i < n; i ++ ) cin >> w[i];sort(w, w + n, greater<int>());dfs(0, 0);cout << ans << endl;return 0;
}

代码思路

  1. 输入与初始化:读取小猫数量 n 和缆车最大承重 m,以及每只小猫的重量 w[],并按重量从大到小排序。
  2. DFS搜索:定义一个深度优先搜索函数 dfs(u, k),其中 u 是当前考虑的小猫索引,k 是当前已经考虑过的缆车数量。
    • 当搜索到的缆车数量 k 大于或等于已知的最小缆车数量 ans 时,提前结束此分支的搜索。
    • 当所有小猫都被考虑过后,更新最小缆车数量 ans
    • 对于每辆缆车,尝试将当前小猫放入(如果总重不超过 m),递归搜索下一个位置的小猫。递归结束后回溯,撤销选择。
  3. 主函数逻辑:初始化数组 sum[] 用于记录每辆缆车的当前载重,然后调用 dfs() 函数,最后输出最小缆车数量 ans

其它代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;int n, m;
int w[N];
int sum[N];
int ans = N;void dfs(int u, int k)
{if(k >= ans) return;if(u == n){ans = k;return;}for(int i = 0; i < k; i ++ )if(sum[i] + w[u] <= m){sum[i] += w[u];dfs(u + 1, k);sum[i] -= w[u];}sum[k] = w[u];dfs(u + 1, k + 1);sum[k] = 0;
}int main()
{cin >> n >> m;for(int i = 0; i < n; i ++ ) cin >> w[i];//sort(w, w + n, greater<int>());dfs(0, 0);cout << ans << endl;return 0;
}

代码思路

  1. 变量定义:

    • n: 表示小猫的数量。
    • m: 表示每辆缆车的最大承重。
    • w[N]: 存储每只小猫的重量。
    • sum[N]: 记录每辆缆车当前的总重量。
    • ans: 初始设置为一个较大的数(N),用于记录最少需要的缆车数量,最终会被更新为实际的最小数量。
  2. 主函数逻辑:

    • 读取小猫数量 n 和缆车最大承重 m
    • 输入每只小猫的重量 w[]。注意代码中去掉了原先对w[]进行排序的部分,这在原始代码中是为了优化搜索过程,因为通常按照重量从大到小处理可以更快达到最优解,但这里为了保持原始逻辑解释,未进行排序。
    • 调用深度优先搜索函数 dfs(u, k) 进行求解,其中 u 表示当前考虑的小猫索引(从0开始),k 表示当前已经分配的缆车数量。
    • 输出最少缆车数量 ans
  3. 深度优先搜索 (DFS) 函数逻辑:

    • 剪枝条件: 当已分配的缆车数量 k 大于等于已知的最小缆车数量 ans 时,直接返回,因为后续的搜索不会得到更好的解。
    • 终止条件: 当所有小猫都被考虑过(即 u == n)时,更新 ans 为当前的缆车数量 k,然后返回。
    • 尝试分配小猫到已有缆车:
      • 遍历之前的所有缆车(用 i 表示),检查当前小猫是否能加入到缆车 i 中(即 sum[i] + w[u] <= m)。
        • 如果可以加入,就临时增加 sum[i] 的值,然后递归调用 dfs 函数尝试分配下一个猫,分配完后再恢复 sum[i] 的值(回溯)。
    • 尝试分配到新缆车:
      • 将当前小猫分配到一个新的缆车(即 sum[k] = w[u]),然后递归调用 dfs 函数分配下一个猫,分配完后清空 sum[k](因为这是尝试过程中的状态,不是最终分配)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

产科管理信息系统源码:产科电子病历、高危孕产妇五色管理系统源码 孕产妇健康管理信息平台源码

产科管理信息系统源码&#xff1a;产科电子病历、高危孕产妇五色管理系统源码 孕产妇健康管理信息平台源码 产科电子病历系统是以采集病人在整个医疗护理过程中所产生的各种信息。包括病案首页、门诊病历、住院病历、出院记录、病人病程记录等全部病历文书&#xff1b;涵盖文字…

宿舍报修小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;故障上报管理&#xff0c;新闻信息管理&#xff0c;维修人员管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;新闻信息…

node.js外卖小程序-计算机毕业设计源码81838

摘要 自从计算机发展开始&#xff0c;计算机软硬件相关技术的发展速度越来越快&#xff0c;在信息化高速发展的今天&#xff0c;计算机应用技术似乎已经应用到了各个领域。在餐饮行业&#xff0c;除了外卖以外就是到店里就餐&#xff0c;在店里就餐如果需要等待点餐的话&…

转盘输入法-单独鼠标版本

序 转盘输入法&#xff0c;给你的聊天加点新意。它不用常见的九宫格或全键盘&#xff0c;而是把字母摆在圆盘上&#xff0c;一滑一滑&#xff0c;字就出来了&#xff0c;新鲜又直接。 单独鼠标版本GIF演示 演示软件下载 转盘输入法https://download.csdn.net/download/u0146…

zdppy+vue3+antd 实现表格数据渲染

基本用法 <template><a-table :columns"columns" :data-source"data"><template #headerCell"{ column }"><template v-if"column.key name"><span>xxx Name</span></template></temp…

免费鼠标连点器有吗?需要付费吗?鼠标连点器电脑版免费推荐6款!

在数字化时代&#xff0c;鼠标连点器成为了许多用户提高工作效率、优化游戏体验的得力助手。然而&#xff0c;面对市场上琳琅满目的鼠标连点器软件&#xff0c;很多用户都会产生疑问&#xff1a;是否有免费的鼠标连点器&#xff1f;它们真的需要付费吗&#xff1f;今天&#xf…

名企面试必问30题(二十二)——你对加班的看法?

1.思路 实际上&#xff0c;很多公司询问此问题&#xff0c;并非表明一定要加班&#xff0c;只是想测试您是否愿意为公司奉献。在回答时&#xff0c;一定不能有诸如不接受加班、不接受 996 等话语&#xff0c;因为没有公司能承诺永远不加班。主要回答应围绕因何原因加班&#xf…

lua入门(1) - 基本语法

本文参考自&#xff1a; Lua 基本语法 | 菜鸟教程 (runoob.com) 需要更加详细了解的还请参看lua 上方链接 交互式编程 Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用&#xff1a; 如下图: 按…

物理删除和逻辑删除区别

物理删除和逻辑删除是数据库管理中针对记录删除操作的两种不同方式&#xff0c;它们的主要区别在于数据的实际处理和后续影响&#xff1a; 物理删除&#xff1a; 操作实质&#xff1a;物理删除会将数据记录从数据库表中彻底移除&#xff0c;包括记录所占的磁盘空间都会被释放。…

Vue3 对跳转 同一路由传入不同参数的页面分别进行缓存

1&#xff1a;使用场景 从列表页跳转至不同的详情页面&#xff0c;对这些详情页面分别进行缓存 2&#xff1a;核心代码 2.1: 配置路由文件 在路由文件里对需要进行缓存的路由对象添加meta 属性 // 需要缓存的详情页面路由 { name: detail, path: /myRouter/detail…

十大排序:插入/希尔/选择/堆/冒泡/快速/归并/计数/基数/桶排序 汇总(C语言)

目录 前言非线性时间比较类插入排序(1) 直接插入排序(2) 希尔排序 选择排序(3) 选择排序优化版(4) 堆排序 交换排序(5) 冒泡排序(6) 快速排序hoare版本挖坑版前后指针版非递归版 归并排序(7) 归并排序递归版非递归版 线性时间比较类(8) 计数排序基数排序与桶排序 总结 前言 在计…

报文交换 和 电路交换对比说明

报文交换 和 电路交换 是两种不同的网络通信方式&#xff0c;它们在数据传输的方式、效率、成本和适用场景等方面有所不同。下面详细对比这两种交换方式&#xff0c;并举例说明。 报文交换&#xff08;Message Switching&#xff09; 定义&#xff1a;报文交换是一种存储-转发…

昇思25天学习打卡营第13天|基于MindSpore通过GPT实现情感分类

基于MindSpore通过GPT实现情感分类 情感分类 情感分类是指在自然语言处理(NLP)领域中,通过分析文本内容所表达的情感倾向,将文本归类为正面、负面或中性等类别的任务。 在情感分类中,基于不同的方法和技术,可以分为基于情感词典的方法、基于传统机器学习的方法和基于深…

c++笔试题

语言特性 题目1&#xff1a;请解释C11中新引入的auto和decltype关键字&#xff0c;并给出使用示例。 题目2&#xff1a;什么是RAII&#xff08;Resource Acquisition Is Initialization&#xff09;&#xff1f;请解释其原理并举例说明。 题目3&#xff1a;C11引入了move se…

【unity实战】使用旧输入系统Input Manager 写一个 2D 平台游戏玩家控制器——包括移动、跳跃、滑墙、蹬墙跳

最终效果 文章目录 最终效果素材下载人物环境 简单绘制环境角色移动跳跃视差和摄像机跟随效果奔跑动画切换跳跃动画&#xff0c;跳跃次数限制角色添加2d物理材质&#xff0c;防止角色粘在墙上如果角色移动时背景出现黑线条方法一方法二 墙壁滑行实现角色滑墙不可以通过移动离开…

Web贵州旅游攻略系统-计算机毕业设计源码16663

目 录 第 1 章 引 言 1.1 选题背景与意义 1.2 国内外研究现状 1.3 论文结构安排 第 2 章 系统的需求分析 2.1 系统可行性分析 2.1.1 技术方面可行性分析 2.1.2 经济方面可行性分析 2.1.3 法律方面可行性分析 2.1.4 操作方面可行性分析 2.2 系统功能需求分析 2.3 系…

前端面试题18(js字符串特定内容查找方法)

在JavaScript中&#xff0c;有多种方法可以用来查找字符串中的特定内容。以下是一些常用的方法&#xff0c;包括它们的用途和示例代码&#xff1a; 1. indexOf() indexOf() 方法返回指定文本在字符串中第一次出现的索引&#xff08;位置&#xff09;&#xff0c;如果没有找到…

初学者打字练习平台推荐

大牛打字练习平台 (ccfoj.com) 适合人群&#xff1a;c初学者&#xff0c;10~20岁不定&#xff0c;有效提高对代码的熟悉程度&#xff0c;以及锻炼打字速度。 TypingClub TypingClub是一个免费的在线打字练习平台&#xff0c;提供各种打字练习内容&#xff0c;从基础到高级。…

pulsar单节点能开启事务吗?是不是真的

Apache Pulsar 支持事务&#xff0c;但是需要在分布式模式下运行。单节点模式下不支持 Pulsar 事务。事务功能在 Pulsar 中依赖于分布式的 BookKeeper 存储服务&#xff0c;以确保事务的持久性和可靠性。 具体来说&#xff1a; 分布式模式和事务支持&#xff1a; 在分布式部署…

MyBatis(26)MyBatis 有哪些方式可以实现多数据源管理

在企业级应用开发中&#xff0c;有时需要同时操作多个数据库&#xff0c;这就涉及到多数据源管理的问题。MyBatis作为一个流行的持久层框架&#xff0c;本身并没有直接提供多数据源管理的功能&#xff0c;但是可以通过与Spring等框架结合&#xff0c;或者通过自定义方式来实现多…