发现宝藏👉 这个输入样例很奇特,其实就是蛇形矩阵
好,归入正题
本人用 DFS+记忆化 完成此题
我们一步一步来分析...
目录
输入
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
scanf ("%d", &a[i][j]);
获取答案
分别枚举每个点,用dfs得到 以这个点为起点能滑的最长长度,再记录最大值
int ans = 0;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
ans = max(ans, dfs(i, j));
算出以这个点为起点能滑的最长长度 DFS
咱们加上记忆化防止超时
int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; //方向数组
int dfs(int x, int y) { //返回从起点开始最多能滑几步(不包含起点)
if (dp[x][y] != 0)
return dp[x][y];
int maxn = 0;
for (int i = 0; i < 4; i ++) {
int dx = x + mov[i][0];
int dy = y + mov[i][1];
if (ok(dx, dy) && a[dx][dy] < a[x][y]) {
maxn = max(maxn, dfs(dx, dy));
}
}
return dp[x][y] = maxn + 1;
}
输出
printf ("%d", ans);
最后代码
//【例9.24】滑雪
#include <iostream>
using namespace std;
const int N = 105;
int n, m, a[N][N], dp[N][N];
int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
bool ok(int x, int y) {
return x > 0 && x <= n && y > 0 && y <= m;
}
int dfs(int x, int y) { //返回从起点开始最多能滑几步(不包含起点)
if (dp[x][y] != 0)
return dp[x][y];
int maxn = 0;
for (int i = 0; i < 4; i ++) {
int dx = x + mov[i][0];
int dy = y + mov[i][1];
if (ok(dx, dy) && a[dx][dy] < a[x][y]) {
maxn = max(maxn, dfs(dx, dy));
}
}
return dp[x][y] = maxn + 1;
}
int main() {
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
scanf ("%d", &a[i][j]);
int ans = 0;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
ans = max(ans, dfs(i, j));
printf ("%d", ans);
return 0;
}
/*
【输入样例】
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
*/
运行结果对比
没加记忆化的DFS
超时一个点!
DSF+记忆化
原题链接:信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)
代码可以拿走,请把赞留下