dp入门:从暴力dfs 到 dp

本篇为小金鱼大佬视频的学习笔记,原视频链接:https://www.bilibili.com/video/BV1r84y1379W?vd_source=726e10ea5b787a300ceada715f64b4bf

基础概念

  暴力dfs很多时候仅能过部分测试点,要想将其优化,一般以 dfs -> 记忆化搜索 -> dp 为路线,后续熟悉后可以直接写出dp代码。

  •    记忆化搜索:在dfs的基础上,增加一个数组用于记录已经被计算过的值,以减少后续的计算来达到优化效果
  •   dp:给定一个问题,将其拆分为无数个可解决的子问题,并将子问题的答案记录下来,根据子问题反推出源问题

  所谓递归,“递”是从上往下,将问题分解为子问题的过程,“归”是从下向上回溯,将已有答案的子问题合并产生答案的过程,而dp就是只调用“归”,从下向上直接找答案

 例题:

本篇以数字三角形为例,分析dfs逐步优化到dp的过程,原题链接:P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

本题目标是要找到从顶部到底部产生的最大权值。

方法一:暴力递归

  由题可知,一个数字只可以走到他下面的两个数,而在数组中该数下标(x,y),则它可以遍历的数字下标为(x + 1,y)和(x + 1,y + 1),要找到最大的权值,因此递归条件为 max(dfs(x + 1, y), dfs(x + 1, y + 1)) + mp[x][y];

  其实以前刚开始学递归时,一直理解不了return后面这个式子,现在从数学公式来理解的话还是有点不明白,但是可以 通过递归搜索树来理解 

#include<iostream>
using namespace std;int n;
const int  N = 1010;
int mp[N][N];
int mem[N][N] = { 0 };int dfs(int x, int y) {if (x > n || y > n) return 0;return max(dfs(x + 1, y), dfs(x + 1, y + 1)) + mp[x][y];
}
//从顶部到底部产生最大权值
int main() {cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j <= i; j++) {cin >> mp[i][j];}}cout << dfs(0,0);return 0;
}

在洛谷上dfs无法通过所有案例,显示tle

方法二:记忆化搜索

  在dfs的基础上,加上一个mem数组用于存储已经计算过的值,可以大大减少计算量

#include<iostream>
using namespace std;int n;
const int  N = 1010;
int mp[N][N];
int mem[N][N] = { 0 };int dfs(int x, int y) {if (mem[x][y]) return mem[x][y];int res = 0;if (x > n || y > n) res = 0;else res = max(dfs(x + 1, y), dfs(x + 1, y + 1)) + mp[x][y];mem[x][y] = res;return res;}int main() {cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j <= i; j++) {cin >> mp[i][j];}}cout << dfs(0,0);return 0;
}

也就是说, 记忆化搜索 = dfs + 记录答案 

同时要注意:

  • 要想实现 记忆化搜索  dfs参数要尽可能少 ,不应该把没影响边界的参数放进来
  • 要想 剪枝 ,就应尽可能把能剪枝的参数写上来

方法三:递推

  递推,也就是从已知答案的小问题逐步推演到源问题的过程,也就是从递归搜索树的下面走到上面回溯的过程,而此过程往往用数组来存储值 。(本题为了便于区分不同方法,用f数组来存储)

  注意: for循环一定注意是从0增还是从n减 ,而这取决于递归搜索树的底部是n还是0。

#include<iostream>
using namespace std;int n;
const int  N = 1010;
int mp[N][N];
int f[N][N] = { 0 };//从顶部到底部产生最大权值
int main() {cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j <= i; j++) {cin >> mp[i][j];}}for (int i = n - 1; i >= 0; i--) {for (int j = 0; j < n; j++) {f[i][j] = max(f[i + 1][j], f[i + 1][j + 1]) + mp[i][j];}}cout << f[0][0];return 0;
}

也可以看出:

  •   递推公式 = dfs向下递归公式  
  •   递推数组初始值 = dfs递归边界  

以上是本文全部内容,如果对你有帮助点个赞再走吧~  ₍˄·͈༝·͈˄*₎◞ ̑̑

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

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

相关文章

JavaEE—— HTTP协议(上篇)

文章目录 一、认识什么是 HTTP 协议二、HTTP 抓包工具1.了解使用哪种工具2.了解抓包工具抓包的原理3.简单使用抓包工具 三、解释 HTTP 中的报文格式1.认识 URL2. 认识 HTTP 请求解释首行 "方法"解释 请求头(header)空行body 3、总结 一、认识什么是 HTTP 协议 HTTP …

PS学习 - 抠图-通道-主题颜色和背景颜色不能相近

抠出蝴蝶 1.通道抠图 套索工具 这里需要圈住你要的&#xff0c;注意尽量小点 ctrl j 复制 然后去掉背景 点击通道 找到明暗对比最大的通道&#xff0c;这里我理解为颜色反差最大的那个&#xff0c;突出你要抠的东西 搜了下说是一般为蓝色 复制通道 ctrll调出色阶 通过移…

Rust 枚举与模式匹配:探索类型安全与表达力的完美结合

Rust 是一种系统编程语言&#xff0c;旨在提供内存安全、并发性和性能。在 Rust 中&#xff0c;枚举&#xff08;Enum&#xff09;和模式匹配&#xff08;Pattern Matching&#xff09;是两个核心概念&#xff0c;它们共同构建了 Rust 强大的类型系统和表达力。本文将深入探讨 …

一文总结python的异常数据处理示例

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

理解java特性:抽象类和接口

抽象类 抽象类的意义何在&#xff1f; 表面上看抽象类就是其中的抽象方法 不写方法体 只写一个方法声明&#xff1a; public abstract void eat(); 这个eat方法 在基类中是一个抽象概念 不知道动物要吃什么 动物是一个总体概念 所以继承它的子类必须实现这个方法 把抽象变为…

springboot278基于JavaWeb的鲜牛奶订购系统的设计与实现

鲜牛奶订购系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统鲜牛奶订购信息管理难度大&…

VMwareWorkstation16与Ubuntu 22.04.6 LTS下载与安装

一、准备工作 VMware Workstation Pro 16官网下载&#xff1a; https://customerconnect.vmware.com/cn/downloads/info/slug/desktop_end_user_computing/vmware_workstation_pro/16_0。下载需要账号登录。 二、安装 双击exe文件稍等一会会弹出安装程序&#xff0c;如图 这…

FUTR3D论文实验环境配置及运行

项目地址&#xff1a;https://github.com/Tsinghua-MARS-Lab/futr3d 论文地址&#xff1a;https://arxiv.org/abs/2203.10642 环境&#xff1a;Linux、cuda 11.1、python 3.8 1.创建虚拟环境futr conda create -n futr python3.8 -y conda activate futr2.安装pytorch的GPU版本…

Vue中nextTick一文详解

什么是 nextTick&#xff1f; 在 Vue 中&#xff0c;当我们修改数据时&#xff0c;Vue 会自动更新视图。但是&#xff0c;由于 JavaScript 的事件循环机制&#xff0c;我们无法立即得知视图更新完成的时机。这时候&#xff0c;我们就需要使用 nextTick 来获取视图更新完成后的…

Spring Boot(六十八):SpringBoot 整合Apache tika 实现文档内容解析

1 Apache Tika 介绍 Apache Tika 是一个开源的内容检测和分析框架,由Apache软件基金会开发和维护的顶级项目。它可以从各种格式的文件中提取元数据和文本内容。Tika非常适合处理全文搜索、内容分析、翻译、内容提取等需要大量处理和分析文档内容的任务。Apache Tika提供了多种…

Airtest-Selenium升级兼容Selenium 4.0,给你全新体验!

一、前言 在上期更新推文中提到&#xff0c;我们Airtest-Selenium更新到了1.0.6版本&#xff0c;新增支持Selenium4.0的语法&#xff0c;那么我们来看一下Airtest-Selenium更新后有什么新的内容吧~ 二、selenium 4.0有什么新功能 selenium4.0最主要的还是定位元素方法的更新…

力扣--最小覆盖子串--双端队列+滑动窗口

滑动窗口思路&#xff08;双端队列实现&#xff09;&#xff1a; 可以参考一下&#xff1a;力扣hot8---滑动窗口-CSDN博客以及力扣hot9---滑动窗口-CSDN博客。 使用滑动窗口有以下几个步骤&#xff1a;初始化双端队列&#xff08;将s的前t_len个元素入队&#xff0c;此时检验是…

spring源码分析-事务的底层源码-1

这里写自定义目录标题 spring事务的源码分析阅读spring事务源码的前置知识JDBC的事务spring当中和事务相关的对象spring应用程序编码spring事务的源码如何开始研究spring源码当中如何代理bean spring事务的源码分析 最近在研究seata&#xff1b;看了一下spring当中的事务有一点…

第十三届蓝桥杯(C/C++ 大学B组)

目录 试题 A: 九进制转十进制 试题 B: 顺子日期 试题 C: 刷题统计 试题 D: 修剪灌木 试题 E: X 进制减法 试题 F: 统计子矩阵 试题 G: 积木画 试题 H: 扫雷 试题 I: 李白打酒加强版 试题 J: 砍竹子 试题 A: 九进制转十进制 九进制正整数 ( 2022 )转换成十进制等于多…

Hypermesh碰撞安全之安全带缠绕建模

进入安全带建模&#xff08;Analysis→safety→belt routing) ①肩带的创建 注&#xff1a;end types: 表示2D和1D单元的过渡方式 ②腰带的创建 ③修改接触系数

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Tabs)

通过页签进行内容视图切换的容器组件&#xff0c;每个页签对应一个内容视图。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 该组件从API Version 11开始默认支持安全区避让特性(默认值为&#x…

【老旧小区用电安全谁能管?】安科瑞智慧用电安全管理系统解决方案

行业背景 电气火灾指由电气故障引发的火灾。每年以30%的比例高居各类火灾原因之首。以50%到80%的比例高居重特大火灾之首。已成为业界重点关注的对象并为此进行着孜孜不倦的努力。 国务院安委会也于2017年5月至2020年4月年开展了为期3年的电气火灾综合治理工作。在各界努力的…

HJ212协议C#代码解析实现

HJ212协议C#代码解析实现 HJ212协议是环保中一个非常重要的标准协议&#xff08;字符串协议&#xff09;&#xff0c;之前写了两篇C HJ212协议解析的相关博文&#xff1a; 环保 HJ212协议解析基于Qt5.14.2的HJ212 TCP服务端接收解析入库程序 最近在学习C#&#xff0c;所以打算…

Liunx系统部署服务应用常用的命令操作

根目录下文件夹的用途 在 Linux 系统中&#xff0c;各个文件夹有着明确的目的和用途。基于您提供的列表&#xff0c;以下是这些文件夹的基本解释&#xff1a; bin: 存放二进制可执行文件&#xff0c;这些是普通用户和系统管理员常用的基本命令和应用程序。 boot: 包含启动 Li…

人工智能的发展与未来

人工智能&#xff08;Artificial Intelligence&#xff0c;简称 AI&#xff09;是一门极富挑战性的科学&#xff0c;它涉及计算机科学、控制论、信息论、语言学、神经生理学、心理学、数学、哲学等多种学科的相互渗透。人工智能的研究课题广泛&#xff0c;旨在让机器学会思考&a…