dp入门:从暴力dfs到dp

news2024/10/7 6:48:16

本篇为小金鱼大佬视频的学习笔记,原视频链接: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.coloradmin.cn/o/1524840.html

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

相关文章

NetSuite多脚本性能研究

在项目中&#xff0c;随着复杂度的提升&#xff0c;客制脚本以及各类SuiteAPP的应用&#xff0c;导致某个对象上挂载的脚本大量增加&#xff0c;最终导致了性能问题。表现在保存单据时时间过长&#xff0c;严重影响人机界面的用户感受。基于此问题&#xff0c;我们开展了NetSui…

谷歌(edge)浏览器过滤,只查看后端发送的请求

打开F12 调试工具 选择Network 这是我们会发现 什么图片 文件 接口的请求很多很多&#xff0c;我们只需要查看我们后端发送的请求是否成功就好了 正常情况我们需要的都是只看接口 先点击这里这个 过滤 我们只需要点击 Fetch/XHR 即可过滤掉其他请求信息的展示 这样烦恼的问题就…

GAN及其衍生网络中生成器和判别器常见的十大激活函数(2024最新整理)

目录 1. Sigmoid 激活函数 2. Tanh 激活函数 3. ReLU 激活函数 4. LeakyReLU 激活函数 5. ELU 激活函数 6. SELU 激活函数 7. GELU 激活函数 8. SoftPlus 激活函数 9. Swish 激活函数 10. Mish 激活函数 激活函数(activation function)的作用是对网络提取到的特征信…

【算法与数据结构】堆排序TOP-K问题

文章目录 &#x1f4dd;堆排序&#x1f320; TOP-K问题&#x1f320;造数据&#x1f309;topk找最大 &#x1f6a9;总结 &#x1f4dd;堆排序 堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 建堆 升序&#xff1a;建大堆 降序&#xff1a;建小堆利…

uni-popup(实现自定义弹窗提示、交互)

一般提示框的样式&#xff0c;一般由设计稿而定&#xff0c;如果用uniapp的showmodel&#xff0c;那个并不能满足我们需要的自定义样式&#xff0c;所以最好的方式是我们自己封装一个&#xff01;&#xff08;想什么样就什么样&#xff09;&#xff01; 一、页面效果 二、使用…

unity学习(61)——hierarchy和scene的全新认识+模型+皮肤+动画controller

刚刚开始&#xff0c;但又结束的感觉&#xff1f; 1.对hierarchy和scene中的内容有了全新的认识 一定要清楚自己写过几个scene&#xff1b;每个scene之间如何跳转&#xff1b;build setting是add当前的scene。 2.此时的相机需要与模型同级&#xff0c;不能在把模型放在相机下…

VScode(8)之阅读大型CC++工程

VScode(8)之阅读大型CC工程(Linux内核)代码 Author&#xff1a;Once Day Date&#xff1a;2023年4月25日/2024年3月17日 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章请查看专栏: VScode开发_Once-Day的博客-CSDN博客 参考文档: 1. 历史包袱 由于上世纪70-80年代的…

Spring Web MVC入门(3)

学习Spring MVC 请求 传递JSON数据 JSON概念 JSON: JavaScript Object Natation JSON是一种轻量的数据交互格式, 采用完全独立于编程语言的文本格式来存储和标识数据. 简单来说, JSON是一种数据格式, 有自己的格式和语法, 使用文本来表示对象或数组的信息, 因此JSON的本质…

Linux网络基础2

目录 实现网络版本计算器 自己定协议实现用json协议实现 重谈OSI七层模型HTTP协议 域名介绍url介绍HTTP请求和响应 实现一个简易的HTTP服务器 实现简易Http服务器初级版实现简易Http服务器中级版 实现一个简易的HTTP服务器最终版 请求方法HTTP状态码HTTP常见的Header 实现网…

The Rise and Potential of Large Language Model Based Agents: A Survey

OpenAI AI的应用研究主管Lilian Weng发布了关于AI Agents的《大语言模型&#xff08;LLM&#xff09;支持的自主代理》&#xff0c;在文章中她定义了基于LLM构建AI Agents的应用框架&#xff1a;AgentLLM&#xff08;大型语言模型&#xff09;记忆&#xff08;Memory&#xff0…

【AI系列】Torchvision、Torchaudio 和 Torchtext关系

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

13 - grace数据处理 - 泄露误差改正 -正演建模法(Forward-Modeling)

grace数据处理 - 泄露误差改正 -正演建模法(Forward-Modeling) *0* 引言*1* Matlab代码实现0 引言 正演建模法最早是由Chen等提出的,本质是通过迭代的思想反求真实信号的过程,为什么要反求呢?因为在数据处理过程中做了球谐截断和空间滤波,使部分有用信号被湮灭,也就是有…

Sentinel篇:线程隔离和熔断降级

书接上回&#xff1a;微服务&#xff1a;Sentinel篇 3. 隔离和降级 限流是一种预防措施&#xff0c;虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。 而要将这些故障控制在一定范围&#xff0c;避免雪崩&#xff0c;就要靠线程隔离…

email + celery+django 异步发送邮件功能的实现

主要流程&#xff1a; django通过发件服务器到收件服务器&#xff0c;最后到收件人 邮件配置设置需要打开SMTP/IMAP并获的授权码&#xff0c;完成授权功能实现发送给收件人 邮件配置请参考另一博客https://blog.csdn.net/qq_44238024/article/details/136277821 项目结构树…

[ROS 系列学习教程] rosbag Python API

ROS 系列学习教程(总目录) 本文目录 1. 构造函数与关闭文件2. 属性值3. 写bag文件内容4. 读bag文件内容5. 将bag文件缓存写入磁盘6. 重建 bag 文件索引7. 获取bag文件的压缩信息8. 获取bag文件的消息数量9. 获取bag文件记录的起止时间10. 获取话题信息与消息类型 rosbag 的 Pyt…

Python 编程中反斜杠 “\” 的作用:作为续行符和转义字符,处理文件路径和正则表达式时需特别注意。

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Python 中的反斜杠 \ 可以被用作续行符&#xff0c;它允许你将一行代码分成多行来书写&#xff0c;以提高代码的可读性。这在处理长字符串、复杂的数学表达式或其他需要多行布局的代码时非常有用。 使…

使用三种方式读取文本文件

文章目录 &#x1f354;需求&#x1f384;思路⭐代码⭐效果&#x1f6f8;注意 在 Java 中&#xff0c;读取文件通常涉及以下几个步骤&#xff1a; 打开文件&#xff1a;首先需要创建一个文件对象&#xff0c;表示要读取的文件。这个文件对象可以包含文件路径、文件名等信息。 …

zookeeper快速入门五:用zookeeper实现服务注册与发现中心

系列&#xff1a; zookeeper快速入门一&#xff1a;zookeeper安装与启动-CSDN博客 zookeeper快速入门二&#xff1a;zookeeper基本概念-CSDN博客 zookeeper快速入门三&#xff1a;zookeeper的基本操作 zookeeper快速入门四&#xff1a;在java客户端中操作zookeeper-CSDN博客…

Tomcat Seeion 集群

部署&#xff1a;nginx服务器&#xff1a;11-11&#xff1b;tomcat1:11-3; tomcat2:11-6 nginx服务器11-11做搭建&#xff1a; [rootmcb-11 ~]# systemctl stop firewalld [rootmcb-11 ~]# setenforce 0 [rootmcb-11 ~]# yum install epel-release.noarch -y [rootmcb…

数据结构试卷第九套

1.时间复杂度 2.树&#xff0c;森林&#xff0c;二叉树的转换 2.1树转二叉树 给所有的兄弟节点之间加一条连线&#xff1b;去线&#xff0c;只保留当前根节点与第一个叶子节点的连线&#xff0c;删除它与其他节点之间的连线&#xff1b;然后根据左孩子右兄弟进行调整&#xf…