一. 题目

image.png

二. 理论

  • 记忆化搜索(Memoization):一种动态规划的技术,用于优化递归算法,避免重复计算子问题。它的核心思想是将已经计算过的子问题结果存储起来,当再次遇到相同的子问题时,直接使用已存储的结果,而不是重新计算。这样可以大幅减少递归调用的次数,提高算法效率。

  • 基本思想

  • 【1】递归求解:首先,使用递归的方法解决问题,将问题分解为子问题。

  • 【2】存储结果:当计算一个子问题的结果时,将其存储在某种数据结构(如数组或哈希表)中。

  • 【3】检查缓存:在计算一个子问题前,先检查是否已经计算过。如果已经计算过,则直接返回存储的结果。

  • 【4】递归终止条件:设置一个终止条件,以防止无限递归。


三. 代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N=310;

int n, m;
int ans;
int g[N][N], f[N][N];//g是地图,
// f[N][N]存储以当前位置作为起点时的最大滑雪长度

class MemorySearch
{
public://下标偏移量
    int dx[4]={-1, 0, 1, 0}, dy[4]={0, 1, 0, -1};
public:
    void initIO()
    {
        // 关闭输入输出缓存,使效率提升
        ios::sync_with_stdio(false);
        // 解除cin和cout的默认绑定,来降低IO的负担使效率提升
        cin.tie(nullptr);
        cout.tie(nullptr);
    }

    MemorySearch()
    {
        initIO(), ans=1;
        fill(f[0], f[0]+N*N, -1);
    }

    //返回以x, y为起点的最长长度
    int dfs(int x, int y)
    {
        if(f[x][y]!=-1) return f[x][y];//这个位置搜到过

        f[x][y]=1;//至少是1
        for(int i=0;i<4;++i)
        {
            int a=x+dx[i], b=y+dy[i];
            if(a<0||a>n-1||b<0||b>m-1||g[a][b]>=g[x][y]) continue;
            f[x][y]=max(f[x][y], dfs(a, b)+1);//根据子节点+1去更新最大值
        }
        return f[x][y];// 返回当前坐标为起点的最大滑雪长度
    }
}ms;

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
            cin>>g[i][j];

    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
            ans=max(ans, ms.dfs(i, j));
    cout<<ans<<endl;
}