关键词:DFS 、 记忆化搜索 、 动态规划
核心思想:使用DFS结合记忆化搜索来解决问题。记忆化搜索可以避免重复计算已经访问过的节点,从而提高效率。
解题步骤:
- 读取输入,初始化矩阵
mat存储滑雪场的高度信息,初始化dp数组用于存储从每个位置出发的最长滑道长度。初始化dx和dy数组表示四个可能的移动方向。 - 定义
dfs(x, y)函数,该函数返回从位置(x, y)开始的最长滑道长度。 - 如果 dp[x][y] 不为0,说明已经计算过,直接返回。否则,初始化 dp[x][y] 为1(即当前位置至少构成长度为1的滑道)。
- 尝试向四个方向移动,如果新位置 (nx, ny) 的高度低于当前位置,则递归调用 dfs(nx, ny) 并更新 dp[x][y]。
- 遍历所有位置,调用
dfs函数并更新答案ans。最后输出答案ans。
时间和空间复杂度:时间复杂度为 O(n * m * 4),简化后为 O(n * m);空间复杂度为 O(n * m)。
#include <iostream>
using namespace std;
// 定义常量,表示矩阵的最大尺寸
const int MAXN = 1e2 + 2;
// 定义四个方向的移动向量
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int n, m;
int mat[MAXN][MAXN];
int dp[MAXN][MAXN] = {0}; // 动态规划数组,存储从每个点出发的最大递增路径长度
int dfs(int x, int y) {
if (dp[x][y] != 0) return dp[x][y]; // 如果已经计算过,直接返回结果
dp[x][y] = 1; // 初始化路径长度为1(至少包含自身)
// 遍历四个方向
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
// 检查新坐标是否在矩阵范围内,且高度是否递减
if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
if (mat[nx][ny] <= mat[x][y]) continue;
// 递归调用,更新从 (x, y) 出发的最大路径长度
dp[x][y] = max(dp[x][y], dfs(nx, ny) + 1);
}
return dp[x][y];
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> mat[i][j];
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
ans = max(ans, dfs(i, j)); // 计算从每个点出发的最大递增路径长度,并更新最终答案
cout << ans << endl;
return 0;
}

京公网安备 11010502036488号