动态规划(DFS -> 记忆化搜索 ->动态规划)

问题一:

首先看一个最经典的问题:上台阶问题。P1255 数楼梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

我们首先看一下,如何用DFS的方法进行解题。

假设我们要上到第5级台阶:

可以看出上到第五级台阶时,可能是由第4级上去的,也可能是从第3级上去的。接下来以此类推。

所有我们很容易想到一个方程:假设F(x)表示上到第X级台阶的方案数。那么不难看出:
F(x) = F(x-1) + F(x-2)

一开始不要多想直接按照常规的DFS进行,

#include<iostream>
using namespace std;
int n;
int dfs(int x)
{if(x==1) return 1;else if(x==2) return 2; return dfs(x-1) + dfs(x-2);
}int main()
{cin>>n;cout<<dfs(n)<<endl;return 0;
}

但是这个过不了;

再看上面的图,发现很多都算了2遍,比如3。

那么来记忆化搜索:

问题二:
1049. 大盗阿福 - AcWing题库

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。

这条街上一共有 𝑁 家店铺,每家店中都有一些现金。

阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。

作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。

他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?

输入格式

输入的第一行是一个整数 T𝑇,表示一共有 𝑇 组数据。

接下来的每组数据,第一行是一个整数 𝑁 ,表示一共有 𝑁 家店铺。

第二行是 𝑁 个被空格分开的正整数,表示每一家店铺中的现金数量。

每家店铺中的现金数量均不超过1000。

输出格式

对于每组数据,输出一行。

该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。

输入样例:

2
3
1 8 2
4
10 7 6 14

输出样例:

8
24

解答题目啦:
首先用DFS的思想想一下:

解释一下:

方块里面的标i记是第i家店。每个店铺都可以进行偷或不偷。但是!当偷了前一个店铺,那么这个店铺就不能再偷了。

还有一点很重要的要注意!我们这里是从第一家(1)先“分”到第4家或第3家,然后还要返回去。也就是说要确定递归的终点,这里可以想到如果到了倒数第一个(4)或倒数第2各(3)都要return 。

那么我们是不是也可以反过来递归呢?
答案当然可以啦。

先看从1开始递归的:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100005;
int n;
int arr[N];
int dfs(int x)
{if(x>n) return 0;//注意这里为什么是只要x>n就可以了?return max(dfs(x+1),dfs(x+2) + arr[x]);
}
int main()
{int T;cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>arr[i];cout<<dfs(1)<<endl;	}return 0;
}

上面有个小细节:为什么当x>n就可以了呢?不是当此时选了3也就停止了吗?以及为什么这样就可以用dfs直接加上一个数了?

我们这样一步一步分析:

发现:4及以上的都必须是0,而选了3时下一个一定是5,所以直接递归0就OK。也不会执行下面的。

现在我们来记忆化搜索:
 

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100005;
int n;
int arr[N];
int mum[N];
int dfs(int x)
{if(mum[x]) return mum[x];int summ = 0;    //创建一个变量用来存储当前节点的数值。if(x>n) summ = 0;  //如果越界那么值为0;else summ = max(dfs(x+1),dfs(x+2) + arr[x]);//否则将DFS的值赋值给summum[x]=summ;  //将summ的值赋值给记忆化数组return summ;  //返回当前层的值。注意如何越界了就不会走else后面的了。这里要和不加else区分开
}
int main()
{int T;cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>arr[i];cout<<dfs(1)<<endl;	memset(mum,0,sizeof(mum));}return 0;
}

有的小伙伴可能会这样想,我要记录最大值,那么我可不可以在DFS函数上面加一个参数呢?这个参数用来记录当前的最大值。

这个思想是可以的,但是我们想一下:加上这个参数能给我们省下什么?加上一个参数,那就说明此时的状态(就是此时的层数和价格组成的笛卡尔积)是一个节点,我们进行记忆化存储的前提是什么?是要存什么?在上面的图中可以看出是要存节点的值(哪一层),现在多加了一个参数,那是不是要用二维数组来存储啊?

而且我们前面在DFS函数中加参数是为了是什么?
是因为这个参数可以影响我们的递归的进行,比如(x1,y1)这个坐标。当然要两个值,因为x和y都不能超出界限,一旦超出那就要return 。和我们这一题比较一下,我们加上当前我们偷的最大值有有什么影响吗?这个最大值没有限制我们递归的进行,所以是不需要加上的,加了反而多此一举。

我们要记住:

当想要剪枝时,在DFS函数中尽可能多的加入可以判断剪枝的参数。

当要记忆化存储时,在DFS函数中尽可能少的加入参数。

接下来,进阶,DP!

对于这个图:

我们的DFS是从4 --> 1 ,然后从1-->4,那我们能不能直接从1到4呢?

答案是可以的:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100005;
int n;
int arr[N];
int mum[N];
int dp[N];
//int dfs(int x)
//{
//	if(mum[x]) return mum[x];
//	int summ = 0;
//	if(x>n) summ = 0;
//	else summ = max(dfs(x+1),dfs(x+2) + arr[x]);
//	mum[x]=summ;
//	return summ;
//}
int main()
{int T;cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>arr[i];
//		cout<<dfs(1)<<endl;	
//		memset(mum,0,sizeof(mum));for(int i=1;i<=n;i++){//dp[i] = max(dp[i-1],dp[i-2] + arr[i-2])//这里i同时加2dp[i+2] = max(dp[i+1],dp[i] + arr[i]);}cout<<dp[n+2]<<endl;;}return 0;
}

可能很多人直接接触DP时,很不理解这个给状态转移方程到底咋来的,我们观察上面,它不就是DFS直接从最底层向上推得来的吗?

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

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

相关文章

oak相机使用oak官网方式标定

目录 一、depthai ROS驱动 一、depthai ROS驱动 &#xff08;1&#xff09;驱动下载地址&#xff1a;2. C 开发快速上手 — DepthAI Docs 0.3.0.0 documentation sudo apt install ./depthai_2.17.1_arm64.deb //运行 Python3 utilities/cam_test.py -mres 400 -cams rgb,m …

探索大模型:袋鼠云在 Text To SQL 上的实践与优化

Text To SQL 指的是将自然语言转化为能够在关系型数据库中执行的结构化查询语言&#xff08;简称 SQL&#xff09;。近年来&#xff0c;伴随人工智能大模型技术的不断进步&#xff0c;Text To SQL 任务的成功率显著提升&#xff0c;这得益于大模型的推理、理解以及指令遵循等能…

自闭症学校排名前十:为星儿点亮未来

在自闭症教育领域&#xff0c;有许多优秀的学校和机构为自闭症儿童提供着专业的帮助和支持。 星贝育园&#xff1a;以其独特的教育理念和个性化的教学方法脱颖而出。学校拥有一支经验丰富、富有爱心的教师团队&#xff0c;为孩子们提供全方位的关爱和教育。注重培养孩子的综合能…

手机通讯录大营救,恢复sim卡联系人的3个重要方法

在数字化世界的浩瀚海洋中&#xff0c;手机通讯录就像一艘承载着人际关系的生命之船。然而&#xff0c;当这艘船遭遇风浪&#xff0c;即sim卡上的联系人信息意外丢失时&#xff0c;我们该如何进行一场惊心动魄的大营救&#xff0c;找回那些珍贵的联系人呢&#xff1f;别担心&am…

Backend - C# 的日志Lognet4

目录 一、安装 log4net 插件 &#xff08;一&#xff09;作用 &#xff08;二&#xff09;操作 &#xff08;三&#xff09;注意 二、配置 &#xff08;一&#xff09;配置AssemblyInfo.cs &#xff08;二&#xff09;配置log4net.config 1. 创建log4net.config文件&#xff08…

空间自回归模型及 Stata 具体操作步骤

目录 一、理论原理 二、数据准备 三、程序代码及解释 四、代码运行结果 一、理论原理 空间自回归模型&#xff08;Spatial Autoregressive Model&#xff0c;SAR&#xff09;是一种用于分析具有空间相关性的数据的统计模型。它假设观测值之间的相关性不仅取决于传统的时间或…

xxl-job从2.3.0升级到2.4.1版本遇到的问题及解决方法

一、maven升级版本 <!-- xxl-job包 --> <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.1</version> </dependency> 二、在nacos对应服务的配置文件增加accessToken配…

精益创业方法论在创业实践中的应用:以乔布斯视角探索创新与变革的艺术——张驰咨询

史蒂夫乔布斯以其非凡的愿景、不懈的迭代精神与对产品极致的追求&#xff0c;成为无数创业者心中的灯塔。本文将借鉴乔布斯的创新思维与精益创业方法论相结合&#xff0c;构建一套融合理论与实践的深度框架&#xff0c;旨在指导创业者在不确定的市场环境中高效探索、快速验证并…

用C# 代码调整16位整数大小端的4种方法

四种方法: short BLC(short s) {byte high (byte)((s - s % 256) / 256); //数字减去 低8位, 得到的数字再除以256得到高8位byte low (byte)(s % 256); //数字对256取余数, 得到低8位byte[] change1 { high, low };return BitConverter.ToInt16(change1); }short BLC2(sh…

使用ffmpeg将一个目录下的mkv格式的视频文件转换成mp4格式

最近学剪辑&#xff0c;从BT种子下载的素材资源都是mkv格式的&#xff0c;不能直接导入到视频剪辑软件中。这种情况下需要用一些格式转换工具进行转换&#xff0c;也可以使用ffmpeg进行编辑。 ffmpeg是一个命令行工具&#xff0c;用来对本地的音频视频软件进行编辑。ffmpeg我也…

【动态规划】回文串问题

一、经验总结 对于回文串问题&#xff0c;传统的以i位置为结尾的状态表示已经不能满足要求&#xff0c;无法推导状态转移方程。应该创建一个二维dp表&#xff0c;将所有子串[i, j]的状态表示出来二维dp表的初始化和填表顺序略微复杂&#xff0c;有时需要借助网格图像分析 二、…

Web安全:SQL注入

一、SQL注入三要素 1、用户可以对输入的参数值进行修改。 2、后端不对用户输入的参数值进行严格过滤。 3、用户修改后的参数值可以被带入后端中成功执行&#xff0c;并返回一定结果。 二、SQL注入原理 简单来说&#xff0c;用户输入的值会被插入到SQL语句中&#xff0c;然后…

秋招突击——7/10——复习{}——新作{在排序数组中查找元素的第一个最后一个位置、搜索旋转排序数组}

文章目录 引言复习新作在排序数组中查找元素的第一个和最后一个位置个人实现参考实现 搜索旋转排序数组个人实现参考实现 总结 引言 复习 新作 在排序数组中查找元素的第一个和最后一个位置 题目链接 注意 非递减序列》元素是递增或者相等&#xff0c;并不是严格递增的找到…

什么软件可以AI生成PPT?交给这5款AI PPT工具就完事

话说在当下快节奏的工作中&#xff0c;PPT制作几乎已经成为不可或缺的一部分~每天不是在做PPT的路上&#xff0c;就是在改PPT的途中。 好在幸运的是&#xff0c;现在可有不少好用的AI PPT制作工具能够来帮助我们轻松应对这一难题&#xff01;今天就来给大家分享5款实在又百搭的…

Autosar网络管理:发出第一帧网络管理报文的方法

Autosar网络管理:发出第一帧网络管理报文的方法 1. 为什么要第一帧发出网络管理报文 很多OEM要求CAN网络管理第一帧发出的是网络管理报文,目的是为了快速唤醒CAN网络 2. 节点外发第一帧报文不是网络管理报文的原因 首先根据AUTOSAR CANNM规范要求,节点要能够发出网络管理…

TCP协议双向网络通讯---Python实现

本篇文章是博主在人工智能、网络通讯等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在Python…

捷配笔记-PCB阻焊颜色对产品有什么影响?

阻焊层也称为阻焊层或阻焊剂。它是一种薄的聚合物层&#xff0c;应用于&#xff08;PCB&#xff09;。阻焊层的目的是保护PCB表面&#xff0c;并有助于防止焊桥。焊桥是两个导体之间的无意连接&#xff0c;通常是由于存在一小块焊料。需要注意的是&#xff0c;阻焊层被视为其单…

electron实现右键菜单保存图片功能

1.创建窗口&#xff0c;加载页面&#xff0c;代码如下&#xff1a; //打开窗口const {ipcMain, BrowserWindow} require("electron") const saveImage require("../ipcMain/saveImage") let win null; ipcMain.handle(on-open-event, (event, args) &g…

数字信号处理及MATLAB仿真(5)——z变换

采样的其他概念咱们后面再慢慢的讲述吧&#xff0c;先把z变换的程序给大家展示一下&#xff0c;总的来说呢&#xff0c;就用一个函数——ztran就行了。在 MATLAB 中&#xff0c;可以使用 ztrans 函数来进行 Z 变换。ztrans 函数用于对离散时间信号或系统进行 Z 变换&#xff0c…

mysql中select语句的执行顺序

执行顺序是什么&#xff1f; Form 这一阶段读取表的数据&#xff0c;并准备执行后续的操作。如果有多表连接&#xff0c;这一步也会涉及连接操作&#xff08;INNER JOIN、LEFT JOIN、RIGHT JOIN、CROSS JOIN 等&#xff09;。 ON 在进行表连接时&#xff0c;使用 ON 关键字指…