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…

lua入门(1) - 基本语法

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

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

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

【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;如果没有找到…

【vue组件库搭建04】使用vitepress搭建站点并部署到github

前言 基于vitePress搭建文档站点&#xff0c;使用github pages进行部署 安装VitePress 1.Node.js 18 及以上版本 2.npm add -D vitepress 3.npx vitepress init 4.将需要回答几个简单的问题&#xff1a; ┌ Welcome to VitePress! │ ◇ Where should VitePress initi…

Cesium 二三维热力图

Cesium 二三维热力图 原理&#xff1a;主要依靠heatmap.js包来实现 效果图&#xff1a;

从零开始使用WordPress搭建个人网站并一键发布公网详细教程

文章目录 前言1. 搭建网站&#xff1a;安装WordPress2. 搭建网站&#xff1a;创建WordPress数据库3. 搭建网站&#xff1a;安装相对URL插件4. 搭建网站&#xff1a;内网穿透发布网站4.1 命令行方式&#xff1a;4.2. 配置wordpress公网地址 5. 固定WordPress公网地址5.1. 固定地…

【LabVIEW学习篇 - 2】:LabVIEW的编程特点

文章目录 LabVIEW的编程特点图形编程天然并行运行基于数据流运行 LabVIEW的编程特点 图形编程 LabVIEW使用图形化的图形化编程语言&#xff08;G语言&#xff09;&#xff0c;用户通过在程序框图中拖放和连接各种节点&#xff08;Nodes&#xff09;来编写程序。每个节点代表一…

LLM - 循环神经网络(RNN)

1. RNN的关键点&#xff1a;即在处理序列数据时会有顺序的记忆。比如&#xff0c;RNN在处理一个字符串时&#xff0c;在对字母表顺序有记忆的前提下&#xff0c;处理这个字符串会更容易。就像人一样&#xff0c;读取下面第一个字符串会更容易&#xff0c;因为人对字母出现的顺序…

idea MarketPlace插件找不到

一、背景 好久没用idea了&#xff0c;打开项目后没有lombok&#xff0c;安装lombok插件时发现idea MarketPlace插件市场找不到&#xff0c;需要重新配置代理源&#xff0c;在外网访问时通过代理服务进行连接 二、操作 ### File-->setting 快捷键 Ctrl Alt S 远端源地…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-53语言模型和数据集

53语言模型和数据集 1.自然语言统计 引入库和读取数据&#xff1a; import random import torch from d2l import torch as d2l import liliPytorch as lp import numpy as np import matplotlib.pyplot as plttokens lp.tokenize(lp.read_time_machine())一元语法&#xf…

类和对象深入理解

目录 static成员概念静态成员变量面试题补充代码1代码2代码3如何访问private中的成员变量 静态成员函数静态成员函数没有this指针 特性 友元友元函数友元类 内部类特性1特性2 匿名对象拷贝对象时的一些编译器优化 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接…

Linux-DNS

DNS域名解析服务 1.DNS介绍 DNS 是域名系统 (Domain Name System) 的缩写&#xff0c;是因特网的一项核心服务&#xff0c;它作为可以将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便的访问互联网&#xff0c;而不用去记住能够被机器直接读取的IP数串。…