以901. 滑雪 - AcWing题库为例
记忆化搜索和DFS:
DFS:在某个方向上滑雪滑倒不能滑为止,然后再回溯继续滑,直到以所有点为起始点全部遍历完
记忆化搜索:用f[i,j]记录,以某点开始滑的最大路径,保证不重复搜索
f[][]二维数组初始化的时候最好统一赋值为-1,如果不进行初始化直接用0判断,此题可以,可是如果遇到一些记忆化搜索的问题要求方案数的时候,初始化是0可能会导致个别情况计算出来的恰好结果是0时,却被认为未遍历过,因此统一赋值为-1就没错了
python版本:
N = 310
high = [[0] * N for _ in range(N)]
f = [[-1] * N for _ in range(N)]
dx = [-1,0,1,0]
dy = [0,1,0,-1]
n,m=map(int,input().split())
for i in range(1,n+1):
ll=list(map(int,input().split()))
high[i][1:m+1]=ll
def dp(x,y):
if f[x][y]!=-1:
return f[x][y]
f[x][y]=1
for i in range(4):
a=x+dx[i]
b=y+dy[i]
if 1<=a<=n and 1<=b<=m and high[x][y]>high[a][b]:
f[x][y]=max(f[x][y],dp(a,b)+1)
return f[x][y]
def DP():
res = 0
for i in range(1,n+1):
for j in range(1,m+1):
res = max(res,dp(i,j))
return res
print(DP())
c++版本:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 310;
int f[N][N], w[N][N];
int n, m;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int dp(int x, int y)
{
int &t = f[x][y];
if (t != -1) return t;
t = 1;
for(int i = 0; i < 4; i ++)
{
int a = dx[i] + x, b = dy[i] + y;
if (a >= 1 && a <= n && b >= 1 && b <= m && w[a][b] < w[x][y]) {
t = max(t, dp(a, b) + 1);
}
}
return t;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
scanf("%d", &w[i][j]);
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;
}