记忆化递归(记忆化搜索)

记忆化递归(记忆化搜索)前言​ 前一篇博客写到入门的dp算法,后来又遇到一个奇怪的变种题目,同样也是可以用dp写的(至少标签是有动态规划)。我看了答案还是有些不能完全理解,于是又去b站翻了翻教程基础DP,其中提到记忆化的递归(也称记忆化搜索),相当于结合了dp和递归的优点(这时我又觉得比DP还厉害),然后就准备写写记忆化递归。目录​ 1.记忆化递归的解释与分析​ 2.记忆化递归的应用一、记忆化递归的解释与分析前面说道它结合了dp和递归的优点,分别是记忆化和逻辑清晰易懂。下面还是结合斐波那契数列的来理解:F(.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺


前言

前一篇博客写到入门的dp算法,后来又遇到一个奇怪的变种题目,同样也是可以用dp写的(至少标签是有动态规划)。我看了答案还是有些不能完全理解,于是又去b站翻了翻教程基础DP,其中提到记忆化的递归(也称记忆化搜索),相当于结合了dp和递归的优点(这时我又觉得比DP还厉害),然后就准备写写记忆化递归。


目录

1.记忆化递归的解释与分析

2.记忆化递归的应用


一、记忆化递归的解释与分析

前面说道它结合了dp和递归的优点,分别是记忆化逻辑清晰易懂

下面还是结合斐波那契数列的来理解:

F(0)=F(1)=1;

F(n)=F(n-1)+F(n-2) (n≥2,n∈N*);

这里直接给出函数代码,再进行解释:

int F(int n){ 
   
    if(n<2)f[n]=1;			//这里f[]是储存数据的数组
	else if(f[n]==0)		//这里是重点
		f[n]=F(n-1)+F(n-2);
	return f[n];
}

代码解释:

第3行中else if的条件很关键:当f[n]没被计算过,就计算一次。也就是说,如果f[n]已经被计算过储存起来了,那就直接用储存的数据,便不用再计算了。

分析优势:

相对于递归,逻辑清晰易懂,就不用说了。

主要是相对于dp的优势。从上一篇知道dp是将基础全部算出来,然后在这个基础上计算出我们要的那个值,减少了相对普通递归的重复计算。

记忆化递归则更加”投机取巧“了,它只计算了需要用的值并储存起来,而其它不会用到的值不去计算,最大化地减少了计算。打个比方,dp就相当于计算了一个方阵上所有的点(无论有没有利用价值),而记忆化递归相当于计算了方阵上有价值的点,因此记忆化递归的运行时间可能比dp还要短。(注意只是可能,因为斐波那契数列无论是dp还是记忆化递归,都是要把前面的值全部算出来的)


二、记忆化递归的应用

感觉没啥写的,就拿分配宝藏来写shui一写shui吧。题目在这里

#include <stdio.h>
int W[201],sum,d[201][20001];
int f(int k,int load);
int max(int a,int b);
int main(void){ 
   
	int n;
	scanf("%d",&n);
	for (int i = 1; i <= n; ++i){ 
   
		scanf("%d",&W[i]);
		sum+=W[i];
	}
	printf("%d\n",sum-2*f(n,sum/2));
	return 0;
}
int f(int k,int load){ 
   
	int ret=d[k][load];
	if(ret==0){ 
   					//这里就是判断是否被计算过
		if(k==0||load==0)return ret;
		if(W[k]>load)ret=f(k-1,load);
		else
			ret=d[k][load]=max( f(k-1,load),(f(k-1,load-W[k])+W[k]) );
	}
	return ret;
}
int max(int a,int b){ 
   
	int m = a;
	if( a < b) m = b;
	return m;
}

我交上去的时候显示运行时间和用dp写的一样。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/164450.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • A*算法之八数码问题 python解法

    A*算法之八数码问题python解法文章目录A*算法之八数码问题python解法问题描述A*算法与八数码问题状态空间的定义各种操作的定义启发式函数的定义人工智能课程中学习了A*算法,在耗费几小时完成了八数码问题和野人传教士问题之后,决定写此文章来记录一下,避免忘记问题描述在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为12380

    2022年4月6日
    61
  • 微信小程序的面试题_小程序面试题汇总

    微信小程序的面试题_小程序面试题汇总小程序面试题简单描述下微信小程序的相关文件类型?一、WXML(WeiXinMarkupLanguage)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件。与html差不多。二、WXSS(WeiXinStyleSheets)是一套样式语言,用于描述WXML的组件样式,与css差不多二、js逻辑处理,…

    2022年4月19日
    62
  • ListView之多种类型Item

    ListView之多种类型Item一、概述一般而言,listview每个item的样式是一样的,但也有很多应用场景下不同位置的item需要不同的样式。拿微信举例,前者的代表作是消息列表,而后者的典型则是聊天会话界面。本文重点介绍

    2022年7月4日
    22
  • 浅谈QFile

    浅谈QFileQFile是QT中用来处理文件方面的类,对于普通的文件读取,写入,都需要用上的。 简单的一个实例:#include”widget.h”#include”ui_widget.h”#include#include#includeWidget::Widget(QWidget*parent):QWidget(parent),

    2022年5月29日
    40
  • WPF Visifire 入门-动态曲线图[通俗易懂]

    WPF Visifire 入门-动态曲线图[通俗易懂]kagula2019-3-18这里用源代码的形式,示范如何画出一个最简单的动态曲线图。开发环境,Visualstudio2017CommunityUpdate5项目类型:WPFC#.NetFramework4.6.1本文适用对象:有两年没有开发C#WPF的程序员,通过这个示例可以快速回忆。下面是运行效果图,不停显示最新生成的十个数据点。让…

    2022年7月21日
    11
  • java如何打印菱形_java实现空心菱形

    java如何打印菱形_java实现空心菱形第一步:首先对图像进行解析想要打印如图所示的形状经过简单分析之后可得出想要打印该图形必须要进行多层循环嵌套分两个部分进行打印第一部分为上半部分前四行他们是递增的关系后半部分后三行为递减关系,由此可以得出我们需要写两个打的循环。并且由于“*”位置的关系我们必须带入空格同时打印所以每个部分需要两个循环控制,即两个大循环每个里面嵌套两个小循环总计四个循环。第二部:对数字进行分析在分析之前我们必…

    2025年5月31日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号