记忆化搜索
一.滑雪
题目来源:滑雪
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 3e2 + 10;
int n, m;
int g[N][N];
int f[N][N];
//(-1 0)(0 1)(1 0)(0 -1)
//上 右 下 左
//int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
//上下左右
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
//返回从x,y开始的且最长的长度
int dp(int x, int y)
{
int &v = f[x][y];//递归dp(a,b)时会用到
if (v != -1) //已经计算过
{
return v;
}
//没有计算过
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 && g[x][y] > g[a][b])
v = max(v, dp(a, b) + 1);//(x,y走向a,b),求f[x][y]max即求f[a][b]max,然后加1
}
return v;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> g[i][j];
memset(f, -1, sizeof f);//标记没有计算过
int res = -1e9;
//遍历每一个点,求最长长度
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;
}