记忆化搜索

记忆化搜索专题 什么是记忆化搜索呢?搜索的低效在于没有能够很好地处理重叠子问题;动态规划虽然比较好地处理了重叠子问题,但是在有些拓扑关系比较复杂的题目面前,又显得无奈。记忆化搜索正是在这样的情况下产生的,它采用搜索的形式和动态规划中递推的思想将这两种方法有机地综合在一起,扬长避短,简单实用,在信息学中有着重要的作用。   用一个公式简单地说:记忆化搜索=搜索的形式+动态规划的思想。   动态规划:就是一个最优化 阅读详情

原文: http://www.cnblogs.com/fu11211129/p/4276213.html 感谢作者。

一. 动态规划

动态规划(dynamic programming),与“分治思想”有些相似,都是利用将问题分 为子问题,并通过合并子问题的解来获得整个问题的解。于“分治”的不同之处在 于,对于一个相同的子问题动态规划算法不会计算第二次,其实现原理是将每一个计算过的子问题的值保存在一个表中。

二. 记忆化搜索

我们常见的动态规划问题,比如流水线调度问题,矩阵链乘问题等等都是“一步接着一步解决的”,即规模为 i 的问题需要基于规模 i-1 的问题进行最优解选择,通常的递归模式为DP(i)=optimal{DP(i-1)}。而记忆化搜索本质上也是DP思想,当子问题A和子问题B存在子子问题C时,如果子子问题C的最优解已经被求出,那么子问题A或者是B只需要“查表”获得C的解,而不需要再算一遍C。记忆化搜索的DP模式比普通模式要“随意一些”,通常为DP(i)=optimal(DP(j)), j < i。

三. 滑雪问题

上图显示为R*C的雪场,R是行数,C是列数。圆圈内的数字表示的是雪场的海拔高度h,根据常识我们知道,滑雪只有从上往下滑行才可能滑的动,现在我们想要求出能够滑行的最长距离,上面的例子我们可以很直接判断出25-24-......-1这个顺时针方向螺旋的滑雪方式可以滑的最远。

那么这个问题如何用编程来实现呢?我们发现这是一个典型的递推,DP(i, j)表示从坐标(i,j)出发所能滑行的最大长度,且有:DP(i, j)=optimal{DP(i±1, j±1)}+1。下面貼上源代碼。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int max_size=110;
int R,C;
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int h[max_size][max_size],dp[max_size][max_size];
int inMap(int x,int y){
    if(x>=0&&x<=R-1&&y>=0&&y<=C-1) return 1;
    return 0;
}
int max2(int a,int b,int c,int d){
    return max(max(a,b),max(c,d));
}
int dfs(int i,int j){
    int nx,ny,down=0,up=0,left=0,right=0;
    if(dp[i][j]) return dp[i][j];
    nx=i+dir[0][0]; ny=j+dir[0][1];
    if(inMap(nx,ny)){
        if(h[i][j]>h[nx][ny]) up=dfs(nx,ny);
    }
    nx=i+dir[1][0]; ny=j+dir[1][1];
    if(inMap(nx,ny)){
        if(h[i][j]>h[nx][ny]) right=dfs(nx,ny);
    }
    nx=i+dir[2][0]; ny=j+dir[2][1];
    if(inMap(nx,ny)){
        if(h[i][j]>h[nx][ny]) down=dfs(nx,ny);
    }
    nx=i+dir[3][0]; ny=j+dir[3][1];
    if(inMap(nx,ny)){
        if(h[i][j]>h[nx][ny]) left=dfs(nx,ny);
    }
    dp[i][j]=max2(up,down,left,right)+1;
    return dp[i][j];
}
int main(){
    scanf("%d%d",&R,&C);
    memset(h,0,sizeof(h));
    memset(dp,0,sizeof(dp));
    for(int i=0;i<R;i++){
        for(int j=0;j<C;j++){
            scanf("%d",&h[i][j]);
        }
    }
    int ans=-1;
    for(int i=0;i<R;i++){
        for(int j=0;j<C;j++){
            ans=max(ans,dfs(i,j));
        }
    }
    printf("%d\n",ans);
}

四. 切棒子问题

给你一根长n英尺的棒子和一份关于该棒子的价目表如下(其中 i = 1,2,3,…,n),请问如何将这根棒子卖出最高的价格,可以对棒子进行切割。

这个题同样是可以利用DP记忆化搜索来实现的,递推公式为DP(n)=optimal{max{price(i)+DP(n-i)|1≤i≤n}}。实现代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int max_size=50;
const int inf=1<<30;
int price[max_size],dp[max_size];
int n;
int dfs(int n){
    if(dp[n]) return dp[n];
    if(n==0) return 0;
    int mmax=-inf;
    for(int i=1;i<=n;i++){
        mmax=max(mmax,price[i]+dfs(n-i));
    }
    dp[n]=mmax;
    return dp[n];
}
int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++) scanf("%d",&price[i]);
        printf("%d\n",dfs(n));
    }
}

五. 01背包问题

问题描述: 有N件物品和一个重量为M的背包。(每种物品均只有一件)第i件物品的重量是w[i],价值是p[i]。求解将哪些物品装入背包可使价值总和最大。思路也很简单,直接看代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int max_size=50;
const int inf=1<<30;
int p[max_size],w[max_size],dp[max_size][max_size];
int n,v;
int dfs(int i,int v){
    if(dp[i][v]) return dp[i][v];
    if(i==0||v<=0) return 0;
    if(w[i]>v) dp[i][v]=dfs(i-1,v);
    else dp[i][v]=max(dfs(i-1,v),dfs(i-1,v-w[i])+p[i]);
    return dp[i][v];
}
int main(){
    while(scanf("%d",&n)!=EOF){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++) scanf("%d",&p[i]);
        for(int i=1;i<=n;i++) scanf("%d",&w[i]);
        scanf("%d",&v);
        printf("%d\n",dfs(n,v));
    }
}

六. 总结

通过前两个例子分析,我们可以得出DP记忆化搜索的算法模板(自己DIY的,大家可以选择参考)

dfs(problem a){
    if(a has been solved) 
        then: consult the record.
    else//get the optimal solution of problem a.
        divide the problem a into several sub-problems(a1,a2,...,ak)
        get the solution of problem a by dfs(a1),dfs(a2),...,dfs(ak).
    finally write the optimal solution into record.
}






记忆化搜索(搜索+dp思想) 一:简介 (1)记忆化搜索 即 搜索+动态规划数组记录上一层计算结果,避免过多的重复计算 算法上依然是搜索的流程,但是搜索到的一些解用动态规划的那种思想和模式作一些保存;一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态。更重要的是搜索还可以剪枝,可能剪去大量不必要的状态,因此在空间开销上往往比动态规划要低很多。 记忆化算法在求解的时候还是按着自顶向下的顺序,但是每求解 阅读详情

相关推荐

算法之记忆化搜索

记忆化搜索其实就是暴力搜索的过程中保存一些已经计算过的状态(思想类似于动态规划,保存计算过的状态),在暴力搜索的过程中利用这些计算过的状态从而减少很大程度上的计算,从而达到时间复杂度上的优化。 1【问题描述】  小明想知道,满足以下条件的正整数序列的数量:  1. 第一项为 n;  2. 第二项不超过 n;  3. 从第三项开始,每一项小于前两项的差的绝对值。  请计算,对于给定的 n,有多少种满足条件的序列。 【输入格式】  输入一行包含一个整数 n。 【输出格式】  输出一个整数,表示答案。答案可能很大

有梦想的小新人的博客 1663

动态规划5:动态规划与记忆化搜索

本期主题:动态规划与记忆化搜索

小辉的数学博客 3721

做形态学方法的团队_“设计形态学”与“第三自然”

文/邱松(清华大学 美术学院)摘要:“设计形态学”是基于“形态学”研究的设计基础学科。“形态”既是该学科研究的主体,又是与其它学科相连接的“纽带”。实际上,不管是供养我们的地球家园,还是神秘莫测的浩瀚宇宙,均由数量纷繁、千姿百态的“形态”构筑而成。形态通常被分成两大类:一类是源于“第一自然”的“自然形态”;另一类是来自“第二自然”的“人造形态”。而这两类形态正是“设计形态学”研究的两条...

weixin_31548723的博客 2683

动态规划与记忆化搜索的区别与联系

记忆化搜索(Memoization)和动态规划(Dynamic Programming, DP)都是解决重叠子问题的高效算法技术,但它们有着不同的实现方式和特点。

2401_84487219的博客 809

AltiumDesigner 09安装过程破解问题 .

首先分享一下破解文件,网上总是下载不到,好不容易下载到了,放在网盘上,有需要的自取。AltiumDesigner 09破解文件。链接:https://pan.baidu.com/s/1ZGvbR_6T51hpcaFbQiMX5w 密码:qwvaAltiumDesigner 09安装安装文件,比较大,包含破解文件:链接:https://pan.baidu.com/s/1mfgragB519jpGfR...

xiaoxiao_rabbit的博客 3万+

在边缘部署实时视觉应用程序

克隆代码库后,压缩源文件夹的内容,并将生成的存档文件上传到上一节中创建的 S3 存储桶中。在本教程中,我们将使用 AWS Greengrass,因为它支持大多数 Windows 和 Linux 设备,包括我们的目标 Jetson AGX Xavier。此外,模型还可以量化到更低的精度,从而加快推理速度,但对于较大的模型,此过程通常较长(约 45 分钟)。本例中的脚本只是启动一个 Bash 环境,切换到解压后的构件目录,最后使用所需的命令行参数运行 Deepstream 应用。每个模型类型都有其独有的格式。

2501_91623519的博客 1296

动态规划概念及其与记忆化搜索的区别

动态规划的基本概念,动态规划与记忆化搜索的区别,以矩阵连乘为例来介绍动态规划

m0_75039094的博客 1386

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

【数据集总结】不透水面积ISA:GAIA、CLUD-Urban、GISA

WW、forever的博客 2159

记忆化搜索与动态规划:原理、实现与比较

记忆化搜索与动态规划:原理、实现与比较

祯的博客 1181

AI智能体丨使用Coze一键生成中式养生视频,39 条作品涨粉 37.9 万!(附保姆级教程)

本文介绍如何利用扣子(Coze)AI智能体工作流高效制作中式养生短视频。该方案通过AI自动生成养生文案、古风插画素材、语音合成和视频剪辑,将传统制作流程从2-3小时缩短至1-2分钟。工作流包含文案创作、音频生成、图片素材制作和视频合成四大模块,采用大模型处理各环节内容,最终输出可直接导入剪映的草稿文件。特别适合希望快速批量制作文化氛围感强、兼具干货与视觉效果的养生内容创作者,效率提升近百倍。

李同学Lino的博客 3028

Java使用POI生成柱状图导出到word文档(柱状图)

本篇文章主要介绍,如何使用Apache POI组件生成柱状图导出到word文档中,具体步骤看下文。 一、实现效果 Java使用POI技术生成柱状图导出到word文档中,最终生成的柱状图如下所示: 二、环境准备 编程语言:Java 第三方依赖:Apache POI Apache POI依赖代码如下所示: <dependencies> <dependency> <groupId>org.apache.poi</groupId.

✅ Java 开发工程师 7376

动态规划与记忆化搜索有什么异同

动态规划和记忆化搜索是两种常用的递归算法,都用于解决重复计算的问题。他们的主要目的都是通过记录已经解决过的子问题的答案,来避免重复计算。 不同点: 1.思想不同:动态规划法是通过分析问题的最优子结构,将问题分解为子问题,逐个求解,并记录结果,再根据记录的结果推导出原问题的答案;而记忆化搜索法是在递归过程中,对于已经求解过的子问题的答案进行记录和保存,避免再次搜索。 2.实现方式不同:动态规划通常采...

weixin_35756637的博客 688

光学设计仿真软件:Code V_(8).场曲和色差校正

通过以上步骤和代码示例,用户可以更好地理解如何在Code V中进行场曲和色差的校正。这些技术不仅有助于提高光学系统的成像质量,还可以为后续的光学设计提供重要的参考。在实际应用中,用户可以根据具体需求选择合适的校正方法和优化策略,以达到最佳设计效果。

kkchenjj的博客 1785

【递归,搜索与回溯算法 & 记忆化搜索】深入理解记忆化搜索算法:记忆化搜索算法小专题

【递归,搜索与回溯算法 & 记忆化搜索】深入理解记忆化搜索算法,记忆化搜索算法小专题详解:1. 实现记忆化搜索的一般步骤;2. 斐波那契数;3. 不同路径;4. 最长递增子序列;5. 猜数字大小Ⅱ;6. 矩阵中的最长递增路径;

OuO-1 的博客 3468

Access查询中的Dlookup函数的妙用

在Microsoft Access中,处理和分析数据的过程中,常常会遇到需要根据条件从其他记录中提取特定数据的情况。这时候,Dlookup函数就成了开发者和数据分析师的得力助手。今天我们将通过一个具体的实例,详细探讨如何利用Dlookup函数来解决复杂的查询问题。

m0_62153576的博客 295

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【记忆化搜索】记忆化搜索算法的对比及总结

记忆化搜索就是一个带 ”备忘录“ 的递归(暴搜、深搜)。动态规划、记忆化搜索、带备忘录的递归,本质都是同一个东西,本质都还是暴力搜索,只不过做了优化!不是所有的递归都能转化为记忆化搜索的,记忆化搜索只适用于出现了大量重复的问题!递归和记忆化搜索,为动态规划解题又多开辟了一条思路,我们可以通过递归和记忆化搜索,想办法转化为动态规划!但并不是所有问题根据这样子转化都会很方便,有可能常规的动态规划(也就是我们前面学的动态规划五部曲)更方便,这都是因人而异,因题而异的!

lirendada的博客 1390

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【递归、搜索与回溯】记忆化搜索

【递归、搜索与回溯】记忆化搜索

fight_p的博客 2275

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

算法:记忆化搜索

概述 记忆化搜索是一种典型的空间换时间的思想。 记忆化搜索的典型应用场景是可能经过不同路径转移到相同状态的dfs问题。 更明确地说,当我们需要在有层次结构的图(不是树,即当前层的不同节点可能转移到下一层的相同节点)中自上而下地进行dfs搜索时,大概率我们都可以通过记忆化搜索的技巧降低时间复杂度。 例子:青蛙过河 题目描述 一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。 给你石子的位置列表 stones(用单

weixin_38889219的博客 1万+

【递归、搜索与回溯算法】记忆化搜索

本篇文章列举了五个经典的LeetCode算法题目,包括斐波那契数、不同路径、最长递增子序列、猜数字大小 II和矩阵中的最长递增路径。我会在每道题中提到每道题的解题思路,并提供解决本题的C++代码。

是阿建吖! 1329

【算法】记忆化搜索

不同路径、最长递增子序列、猜数字大小 ||、矩阵中的最长递增路径

Code Space 1651

记忆化搜索专题篇

题目包括:斐波那契数,不同路径,最长递增子序列,猜数字大小II,矩阵中的最长递归路径

. 2693
上一篇: nyoj248 BUYING FEED
下一篇: hdu1950 poj1631 Bridging signals(n*logn的最长递增子序列)
勤勤勤能补拙
博客等级 码龄10年 60粉丝 155原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值