dfs记忆化搜索,动态规划

news2024/9/20 3:58:45

动态规划概念:

给定一个问题,将其拆成一个个子问题,直到子问题可以直接解决。然后把子问题的答案保存起来,以减少重复计算。再根据子问题的答案反推,得出原问题解。

821

运行时间长的原因:

重复大量计算

以5个台阶为例:

 正确做法:记录台阶已有的方案,比如用mem[]数组记录

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=30;
int n;
string words[N];//存单词
int used[N];//记录每个单词的使用次数
int g[N][N];//f[i][j] 存第i个单词能否接到第j个单词后面,存储相同子串长度
int res=0;
int mem[N];
int dfs(int x)//x代表遍历到的单词
{

if(mem[x])return mem[x];//如果以计算好直接返回
int sum=0;
if(x==1)
sum=1;
else if(x==2)//用else if
sum=2;
else sum=dfs(x-1)+dfs(x-2);
mem[x]=sum;//没有计算好则需要更新
return sum;
}
int main()
{
scanf("%d",&n);
int res=dfs(n);
printf("%d\n",res);
return 0;
}

递推算法dp:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=30;
int n;
int res=0;
int mem[N];
int main()
{
scanf("%d",&n);
mem[1]=1;
mem[2]=2;
if(n==1||n==2)
printf("%d",mem[n]);
for(int i=3;i<=n;i++)
{
mem[i]=mem[i-1]+mem[i-2];
}
printf("%d\n",mem[n]);
return 0;
}

进一步优化空间:

int newf=0,tmp1=1,tmp=2;

for(int i=3;i<=n;i++)

{

newf=tmp1+tmp2;

tmp1=tmp2;

tmp2=newf;} 

 记忆化搜索=暴力dfs+记录答案

递推的公式=dfs向下递归的公式

递推数组的初始值=递归的边界

acw1049

暴力搜索,分析图:

思路:最后一家店x只有两个可能,被选或者不被选,因为要尽可能的累加数值,所以被选的情况是一直累加到x-2,不被选的情况是只累加到x-1便结束

用home[N]数组保存已经选择的店家。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=30;
int n,k;
int res=0;
int mem[N];
int dfs(int x)//当前遍历到哪个店家
{
if(x>n)return 0;//dfs(5),dfs(6)都等于0,最终是可以组合的n个数字相加取最大值
else
return max(dfs(x+1),dfs(x+2)+mem[x]);//没被选择则是下一个数字,被选中则是隔一个数字
}
int main()
{
scanf("%d",&k);
while(k--)//循环输入k组数据
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//位置是从1开始
{
scanf("%d",&mem[i]);//输入n个数字
}
int sum=dfs(1);
printf("%d\n",sum);
}

return 0;
}

动态规划思路:存储已知方案

注意:方案数组每次遍历完成后需要初始化

拓展:memset()函数

void *memset(void *s, int ch,size_tn);

函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法[1]

memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组,c:是赋给buffer的值,count:是buffer的长度。

此处可以采用memset(mem,0,sizeof mem);对数组清0

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=30;
int n,k;

int mem[N];
int s[N];//记录走到当前位置的财富总和
int dfs(int x)//当前遍历到哪个店家
{int sum=0;
if(s[x]) return s[x];
if(x>n) sum=0;
else
sum=max(dfs(x+1),dfs(x+2)+mem[x]);//没被选择则是下一个数字,被选中则是隔一个数字
//sum不是累加,而是更新,所以不需要清0
s[x]=sum;//记录数据,需要更新
return sum;
}
int main()
{
scanf("%d",&k);
while(k--)//循环输入k组数据
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//位置是从1开始
{
scanf("%d",&mem[i]);//输入n个数字
}
memset(s,0,sizeof s);//更新数组
int res=dfs(1);
printf("%d\n",res);
}
return 0;
}

s[i]存储的是:从i店铺开始能够获取的最大价值 

要实现记忆化搜索,dfs的参数就要尽可能的少,不应该把没有影响边界的参数放进来。

递推算法dp:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=30;
int n,k;
int F1[N];
int mem[N];
int s[N];//记录走到当前位置的财富总和
int main()
{
scanf("%d",&k);
while(k--)//循环输入k组数据
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//位置是从1开始
{
scanf("%d",&mem[i]);//输入n个数字
}
memset(s,0,sizeof s);//更新数组
for(int i=n;i>=1;i--)//递推是由下往上,从f[4]=0开始递推
{
if(i>n)
F1[i]=0;
else
F1[i]=max(F1[i+1],F1[i+2]+mem[i]);
}
printf("%d\n",F1[1]);
}
return 0;
}

 做法是1~n探查,递推返回则从n回到1

想用1-n做递推,则需要从n开始枚举

F1[i]=max(F1[i-1],F1[i-2]+mem[i]);//当i为1,2时数组下标出现负数,下标同时加2得:

F1[i+2]=max(F1[i+1,F1[i]+mem[i]);

空间优化:

for(int i=1;i<n=;i++)

{newf=max(tmp1,tmp2+mem[i]);

tmp2=tmp1;

tmp1=newf;

}

  • 使用两个变量tmp1tmp2来存储前一个位置的最大财富和当前位置不选择前一个位置时的最大财富。
  • 通过一个循环,计算到每个位置时的最大财富,并存储在newf中。
  • 打印出最后一个位置的最大财富。

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

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

相关文章

IT革新狂潮:引领未来的技术趋势

方向一&#xff1a;技术革新与行业应用 当前现状&#xff1a; 量子计算&#xff1a;量子计算的研究正在加速&#xff0c;尽管目前仍处于初级阶段&#xff0c;但其在药物研发、加密技术和材料科学等领域的应用潜力已被广泛认可。 虚拟现实&#xff08;VR&#xff09;与增强现实…

算法学习笔记(5.0)-基于比较的高效排序算法-归并排序

##时间复杂度O(nlogn) 目录 ##时间复杂度O(nlogn) ##递归实现归并排序 ##原理 ##图例 ##代码实现 ##非递归实现归并排序 ##释 #代码实现 ##递归实现归并排序 ##原理 是一种基于分治策略的基础排序算法。 1.划分阶段&#xff1a;通过不断递归地将数组从中点处分开&…

python之pyQt5实例:树莓派+MPU6050采集数据

1、安装必要的软件包&#xff1a; sudo apt-get update sudo apt-get install python3-smbus python3-dev i2c-tools sudo apt-get install python3-smbus 2、确认I2C接口已经启用&#xff1a; 运行 sudo raspi-config 命令打开Raspberry Pi配置工具。 在菜单中选择 "…

ThreadLocal,一次到位

一、定义 ThreadLocal是线程私有变量&#xff0c;用于保存每个线程的私有数据。 那么什么情况下需要进行线程隔离 二、源码分析 public class ThreadLocalTest01 {ThreadLocal<Integer> t new ThreadLocal<>();public void test() {t.set(1);Integer integer…

如果你还不了解双亲委派模型,来看看这篇吧

文章首发于【Java天堂】&#xff0c;跟随我探索Java进阶之路&#xff01; 类与类加载器 类是由它的类加载器加载进虚拟机中的&#xff0c;在同一个Java虚拟机中&#xff0c;对于同一个Class文件&#xff0c;如果采用不同的类加载器&#xff0c;得到的是不相等的类&#xff0c;…

k8s二进制部署--多master、负载均衡、高可用

目录 1、环境准备 1.1 服务器配置 1.2 master02 节点部署 2、负载均衡部署 2.1 下载nginx 2.2 修改nginx配置文件 2.3 启动nginx 2.3.1 检查配置文件语法 2.3.2 启动nginx服务&#xff0c;查看已监听6443端口 3. 部署keepalived服务(nginx主机&#xff0c;以nginx01为…

十一.吊打面试官系列-JVM优化-深入JVM类加载机制

前言 从本篇文章开始我们来探讨JVM相关的知识&#xff0c;内容附带JVM的启动&#xff0c;JVM内存模型&#xff0c;JVM垃圾回收机制&#xff0c;JVM参数调优等&#xff0c;跟着文章一步一步走相信你对JVM会有一个不一样的认识&#xff0c;如果觉得文章对你有所帮助请给个好评吧…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt 驾校管理系统 设计与实现

一.项目介绍 系统角色&#xff1a;管理员、驾校教练、学员 管理员&#xff1a; 个人中心&#xff1a;修改密码以及个人信息修改 学员管理&#xff1a;维护学员信息&#xff0c;维护学员成绩信息 驾校教练管理&#xff1a;驾校教练信息的维护 驾校车辆管理&…

水离子雾化壁炉与会所房间的氛围搭配

水离子雾化壁炉在会所房间的氛围搭配可以为房间增添舒适、温馨和现代感&#xff0c;以下是一些建议&#xff1a; 主题定位&#xff1a; 根据会所房间的主题和定位选择合适的水离子雾化壁炉款式和设计风格。可以是现代简约、欧式古典或是豪华奢华&#xff0c;确保与房间整体风格…

Java基础学习笔记二

Java基础学习笔记二 6 File1.File类1.1File类概述和构造方法【应用】1.2File类创建功能【应用】1.3File类判断和获取功能【应用】1.4File类删除功能【应用】 2.递归1递归【应用】2递归求阶乘【应用】3递归遍历目录【应用】 3.IO流1 IO流概述和分类【理解】2字节流写数据【应用】…

HL7协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.介绍2.传输协议规范2.1. MLLP2.1.1. 数据头定义2.1.2. 转义字符集 2.2. 规范说明2.3. 消息格式说明 3.HL7结构介绍3.1. 患者建档&#xff08;ADT^A28&#xff09;…

AI应用之智能体介绍

AI应用之智能体介绍 一、LLM介绍二、智能客服应用1&#xff0c;阿里智能能话机器人2&#xff0c;华为对话机器人3&#xff0c;公司基于讯飞知识库和讯飞大模型的智能客服 三、大模型应用平台介绍1&#xff0c;fastgpt2&#xff0c;毕昇3&#xff0c; 字节海外版&#xff08;科学…

学习Nginx(二):版本介绍和安装

版本 Nginx官方定义了Mainline、Stable、Legacy三种版本。 1. Mainline version&#xff08;主线版本&#xff09; 该版本包含最新的功能和bug修复&#xff0c;被视为开发版&#xff0c;即正在活跃开发中的版本。其版本号通常为单数&#xff0c;例如1.25.5。这个版本的更新较快…

Nvidia Jetson编译安装Opencv With CUDA,完善GSTREAMER功能

简介 Nvidia Jetson 官方刷机流程结束以后&#xff0c;虽然安装了opencv&#xff0c;但是此版本是CPU版本&#xff0c;并且不包含Cpp版本。如果想要完整的OpenCV支持&#xff0c;需要从源码编译。本文介绍如何下载编译&#xff0c;并安装OPENCV库&#xff0c;并获得完整的CUDA…

必应bing广告开户费用介绍,必应搜索广告推广开户服务!

微软必应Bing搜索引擎广告成为了企业提升品牌知名度与市场份额的有效途径之一&#xff0c;作为全球第二大搜索引擎&#xff0c;在中国市场正逐步展现出其独特的广告价值与潜力。对于希望拓展在线市场的中国企业而言&#xff0c;通过云衔科技开启必应Bing国内广告推广之旅&#…

谷歌外贸seo优化怎么做?

一般有两种选择&#xff0c;在大型电商平台开展业务&#xff0c;如亚马逊&#xff0c;阿里巴巴等平台&#xff0c;也可以选择搭建自己的独立站 选择在大型电商平台可以方便迅速建立起自己的商铺&#xff0c;不需要考虑太多交易&#xff0c;支付&#xff0c;物流等方面的问题&am…

2024.05.14 Diffusion 代码学习笔记

配环境 我个人用的是Geowizard的环境&#xff1a;https://github.com/fuxiao0719/GeoWizard。 出于方便考虑&#xff0c;用的pytorch官方的docker容器&#xff0c;因此python版本&#xff08;3.10&#xff09;和原作者&#xff08;3.9&#xff09;不同&#xff0c;其余都是一…

Java小游戏之汤姆猫

背景&#xff1a; 博主写过羊了个羊小游戏&#xff0c;客户觉得羊了个羊同学写过了&#xff0c;想换一个&#xff0c;于是笔者想到了汤姆猫。就是那个以前在苹果手机上的猫。 过程&#xff1a; 初始会有一个猫的图片展示&#xff0c;然后你点击按钮&#xff0c;猫会有不同动作…

力扣刷题 day2

快乐数 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09;   图: java // 快乐数 --> 19 > 1^2 9 ^2 82 > 82 > 8 ^ 2 2 ^ 2 ......public boolean isHappy(int n) {// 使用快慢指针int slow n, fast getSum(n);while (slow ! fast) {slow getSum(slo…

【Day3:JAVA运算符、方法的介绍】

目录 1、运算符1.1 赋值运算符1.2 比较运算符1.3 逻辑运算符1.3.1 逻辑运算符概述1.3.2 逻辑运算符分类1.3.3 短路的逻辑运算符 1.4 三元运算符1.5 运算符优先级 2、方法2.1 方法介绍2.2 方法的定义和调用格式2.2.1 方法的调用2.2.2 带参数方法的调用2.2.3 带返回值方法的调用2…