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

记忆化递归(记忆化搜索)前言​ 前一篇博客写到入门的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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c#子窗口与父窗口_主窗体控制子窗体的显示

    c#子窗口与父窗口_主窗体控制子窗体的显示方法较为简单,直接撸代码父窗口代码using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Form…

    2022年8月18日
    6
  • Go语言面试题汇总[通俗易懂]

    Go语言面试题汇总[通俗易懂]正在准备golang面试的小伙伴,很荣幸,你能看到这篇文章,希望每一个看到这篇分享的小伙伴都能找到自己称心如意的工作!1、说说go语言的main函数(1)、main函数不能带参数。(2)、main函数不能定义返回值。(3)、main函数所在的包必须为main包。(4)、main函数中可以使用flag包来获取和解析命令行参数。2、在go语言中,new和make的区别?new函数是内建函…

    2022年6月17日
    110
  • python 微信自动回复机器人

    python 微信自动回复机器人python微信自动回复机器人导入wxautohttps://github.com/cluic/wxauto#!python3#-*-coding:utf-8-*-“””Author:tikic@qq.comSource:https://github.com/cluic/wxautoLicense:MITLicenseVersion:3.3.5.3″””fromtokenizeimportNamefromunicodedataimportnameim

    2022年10月1日
    4
  • 单片机入门到高级开挂学习路径(附教程+工具)[通俗易懂]

    单片机入门到高级开挂学习路径(附教程+工具)[通俗易懂]一、先帮大家解答几个问题:1.单片机是什么?答:单片机就是一个微型CPU,把程序烧录芯片里面,通过控制不同的外围电路实现不同产品的功能。2.学单片机编程对数学英语有要求吗?答:数学会基本的加减乘除就行,英语会认单词a-z就行,很多外行人看到代码里一堆英文就头嗡嗡响,其实不然,只有少数语法是固定的,大多数英文都是工程师自己定义的,比如大神你也可以定义成DaShen(中文缩写)。那很多人此时就开始质疑,当初这么辛苦学数学和英语到底是为毛?数学和英语不是单片机开发的门槛,但却决定你以后能达到的高度,

    2022年6月10日
    60
  • SpringAOP学习–SpringAOP简介及原理

    SpringAOP学习–SpringAOP简介及原理前文对AOP做了介绍,实际项目中,一般不会直接上手手动实现aop,而是使用一些高级封装的aop实现,如SpringAOP。Spring是一个广泛应用的框架,SpringAOP则是Spring提供的一个标准易用的aop框架,依托Spring的IOC容器,提供了极强的AOP扩展增强能力,对项目开发提供了极大地便利。前文提到AOP的实现有AspectJ、JDK动态代理、CGLIB动态代理,SpringAOP不是一种新的AOP实现,其底层采用的是JDK/CGLIB动态代理。JDK动态代理回顾上一篇简单介绍了

    2022年8月11日
    6
  • leetcode题目分类_最长前缀匹配例题

    leetcode题目分类_最长前缀匹配例题原题链接编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。示例 1:输入:strs = [“flower”,”flow”,”flight”]输出:”fl”示例 2:输入:strs = [“dog”,”racecar”,”car”]输出:””解释:输入不存在公共前缀。 提示:0 <= strs.length <= 2000 <= strs[i].length <= 200strs[i] 仅由小写英文字母组成题解分

    2022年8月8日
    10

发表回复

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

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