记忆化搜索:滑雪

题目链接:https://www.acwing.com/problem/content/903/
题意:给定一个R行C列的矩阵,表示一个矩形网格滑雪场。
矩阵中第 i 行第 j 列的点表示滑雪场的第 i 行第 j 列区域的高度。
一个人从滑雪场中的某个区域内出发,每次可以向上下左右任意一个方向滑动一个单位距离。
当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
数据范围
1≤R,C≤300,
0≤矩阵中整数≤1e4
输入样例:
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+记忆化的题。
代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int N = 305;
int n,m;
int s[N][N];
int f[N][N];//所有从(i,j)出发路径中的最大值
int way[4][2] = {{0,-1},{0,1},{1,0},{-1,0}};//有四个方向可走
int dfs(int x, int y)
{
    int &v = f[x][y]; //所有v等价于f[x][y]
    if(v != -1) return v;
    v = 1;//初始化一下,至少能走当前的一步
    for(int i = 0; i < 4; i ++ ){
        int a = x + way[i][0];
        int b = y + way[i][1];
        if(a >= 1 && a <= n && b >= 1 && b <= m && s[a][b] < s[x][y])
            v = max(v, dfs(a, b) + 1);
    }
    return v;
}
int main()
{
    scanf("%d%d",&n, &m);
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
            scanf("%d", &s[i][j]);
    memset(f, -1, sizeof f);
    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\n",ans);
    return 0;
}

发布了61 篇原创文章 · 获赞 0 · 访问量 972

猜你喜欢

转载自blog.csdn.net/Satur9/article/details/104055341