首页 > 编程语言 >算法学习笔记(50)——记忆化搜索

算法学习笔记(50)——记忆化搜索

时间:2023-01-07 19:12:56浏览次数:63  
标签:24 25 le int 矩阵 50 笔记 算法 滑雪场

记忆化搜索

题目链接:AcWing 901. 滑雪

题目描述

给定一个 \(R\) 行 \(C\) 列的矩阵,表示一个矩形网格滑雪场。

矩阵中第 \(i\) 行第 \(j\) 列的点表示滑雪场的第 \(i\) 行第 \(j\) 列区域的高度。

一个人从滑雪场中的某个区域内出发,每次可以向上下左右任意一个方向滑动一个单位距离。

当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。

下面给出一个矩阵作为例子:

 1  2  3  4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

在给定矩阵中,一条可行的滑行轨迹为 \(24−17−2−1\)。

在给定矩阵中,最长的滑行轨迹为 \(25−24−23−…−3−2−1\),沿途共经过 \(25\) 个区域。

现在给定你一个二维矩阵表示滑雪场各区域的高度,请你找出在该滑雪场中能够完成的最长滑雪轨迹,并输出其长度(可经过最大区域数)。

输入格式

第一行包含两个整数 \(R\) 和 \(C\)。

接下来 \(R\) 行,每行包含 \(C\) 个整数,表示完整的二维矩阵。

输出格式

输出一个整数,表示可完成的最长滑雪长度。

数据范围

\(1 \le R,C \le 300\),
\(0 \le 矩阵中整数 \le 10000\)

输入样例

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

输出样例

25

状态表示

\(f(i,j)\) 表示所有从\((i,j)\)这个格子开始滑的路径的最大长度。

状态转移

按照第一步是往哪个方向滑的,将所有的路径分为四类(上下左右)

\[f(i, j) = \max[f(i-1,j), f(i+1,j), f(i,j-1),f(i,j+1)] + 1 \]

一般情况下写代码,经常关注的是时间复杂度和空间复杂度,而还需要考虑的一点是代码复杂度。记忆化搜索的代码复杂度很低,采用了递归形式。

#include <iostream>
#include <cstring>

using namespace std;

const int N = 310;

int n, m;
int h[N][N];
int f[N][N];

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int dp(int x, int y)
{
    int &v = f[x][y];
    if (v != -1) return v;
    
    // 最短情况下可以走当前所在的格子,所以初始化为1
    v = 1;
    for (int i = 0; i < 4; i ++ ) {
        int a = x + dx[i], b = y + dy[i];
        if (a >= 1 && a <= n && b >= 1 && b <= m && h[a][b] < h[x][y])
            v = max(v, dp(a, b) + 1);
    }
    
    return v;
}

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            cin >> h[i][j];
    
    // 初始化为-1表示所有状态都还没有计算过
    memset(f, -1, sizeof f);
    
    int res = 0;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            res = max(res, dp(i, j));
            
    cout << res << endl;
    
    return 0;
}

标签:24,25,le,int,矩阵,50,笔记,算法,滑雪场
From: https://www.cnblogs.com/I-am-Sino/p/17033289.html

相关文章

  • JavaScript学习笔记-in运算符
    in运算符判断是否含有指定的属性  通过运算符可以检查一个对象中是否含有指定的属性,如果有返回true,没有则返回false。语法:  "属性名"in对象实例://创建一个对......
  • 算法学习笔记(49)——树形DP
    树形DP题目链接:AcWing285.没有上司的舞会题目描述Ural大学有\(N\)名职员,编号为\(1∼N\)。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个......
  • FFT(快速傅里叶变换)学习笔记
    前言懒得写前言。希望学到后面的数学知识不要放弃,写在这里督促自己。(作为一个没有接触过复数的萌新)感觉再不学点东西就真的可以退役了。什么是FFT?FFT是一种将多项式......
  • 贝叶斯思维第二版笔记之条件概率
    DataFrameis2-Darray,Seriesis1-Darray例子1:democrat=(gss['partyid']<=1)gssisaDataFramefromCSV,gss['partyid']取出gss这一列,而DataFrame的每一列......
  • cuda学习笔记5——CUDA实现图像形态学腐蚀、膨胀
    cuda学习笔记5——CUDA实现图像形态学腐蚀、膨胀​​代码​​​​linux如何编译cuda和opencv代码​​代码#include"cuda_runtime.h"#include"device_launch_parameters.h"......
  • 【学习笔记】分治
    分治相关的东西我基本都不会。CDQ分治最经典的分治,一般用于去掉一层偏序。对于一个区间\([l,r]\)的答案,我们可以找一个中点\(mid\),递归计算出\([l,mid]\)的答案......
  • 设计模式学习笔记
    静态工厂工厂方法可以隐藏创建产品的细节,且不一定每次都会真正创建产品,完全可以返回缓存的产品,从而提升速度并减少内存消耗。里氏替换原则返回实现接口的任意子类都可以......
  • 安全帽识别算法技术原理
    应用背景:安全帽作为一种最常见和实用的个人防护用具,能够有效地防止和减轻外来危险源对头部的伤害。但在现场操作过程中,安全帽的佩戴很容易人为忽略,引发了不少人身伤害事故。......
  • 2023.1.7学习笔记
    、经典类与新式类经典类:​不继承object的类或者其子类的类新式类:​继承object或者其之类的类​在python3中,只有新式类,所有类都默认继承object​在python2中,区......
  • Simpson - 辛普森法 学习笔记
    Simpson-辛普森法学习笔记目录Simpson-辛普森法学习笔记更好的阅读体验戳此进入目的拟合广义积分(反常积分)定义收敛性判断写在前面Simpson公式自适应积分例题#1题面S......