• 洛谷:P1434 [SHOI2002] 滑雪 题解


    题目:

    P1434 [SHOI2002] 滑雪 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    本题关键字:记忆化搜索。

    首先,这题为什么会想到记忆化?(知道的人直接跳过)

    在dfs每种情况是,可能这个点之前已经搜过了,没必要再去搜索了,因此不如存储记住,就没必要再去dfs了。


    本题的主要思路:

    1.先去想dfs怎么做:

    这题每个点出发有可能,所以我们每个点都要开始dfs,最后取他们的最大值。

    dfs部分和类似的迷宫差不多,用两个数组表示4个方向:

    1. dx[4]={0,0,1,-1};
    2. dy[4]={1,-1,0,0};

    改变方向直接xx=x+dx[i] , yy=y+dy[i]

    接下来判断这个方向是否在地图范围内,即

    1. if(xx>0&&xx<=R&&yy>0&&yy<=C)

    当然还要判断这个点是否能滑到,也就是高度要前一个低:

    if(a[xx][yy]<a[x][y])//a为高度
    

    很明显,因为低的不可能滑向高的,所以我们不需要再开一个数组去记录这个点是否走过。

    接下来,就要往四个方向搜索,取四个方向中距离最长的,然后+1,这就是这个点的结果了。

    2.记忆化搜索怎么写

    很显然,直接dfs会TLE。那么就需要记忆化来优化。

    用s[i][j]表示从(i,j)点出发能走的最长距离。

    每次搜索一次记忆一次即可。

    下面给刚接触不怎么明白的人举例:(已经理解的人跳过)

    由于样例不好讲我自己举例子:

    1. 3 3
    2. 1 1 3
    3. 2 3 4
    4. 1 1 1

    先去找(1,1)的最长距离,很明显为1

    接着找(1,2)的最长距离,很明显为1

    接着找(1,3)的最长距离,为2((1,3)->(1,2))

    然后找(2,1)的最长距离,为2((2,1)->(1,1))

    然后是(2,2)的最长距离,如果没有记忆化,那么搜索过程为:(2,2)->(2,1)->(1,1)

    但是(2,1)之前已经搜过了,再去搜就是浪费时间,之前搜索已经知道(2,1)的值为2,那么搜索过程就是缩短为:(2,2)->(2,1),即为3

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define x first
    6. #define y second
    7. using namespace std;
    8. const int N = 110;
    9. typedef pair<int, int> PII;
    10. int ans;
    11. int n, m;
    12. int mp[N][N];
    13. int dist[N][N];
    14. int dx[4] = {-1, 1, 0, 0};
    15. int dy[4] = {0, 0, -1, 1};
    16. int dfs(int s1, int s2)
    17. {
    18. if (dist[s1][s2]) return dist[s1][s2];//记忆化搜索
    19. dist[s1][s2] = 1;
    20. for (int i = 0; i < 4; i ++ )
    21. {
    22. int x = s1 + dx[i], y = s2 + dy[i];
    23. if (x < 1 || x > n || y < 1 || y > m) continue;
    24. if (mp[x][y] >= mp[s1][s2]) continue;
    25. dfs(x, y);
    26. dist[s1][s2] = max(dist[s1][s2], dist[x][y] + 1);
    27. }
    28. return dist[s1][s2];
    29. }
    30. int main()
    31. {
    32. cin >> n >> m;
    33. for (int i = 1; i <= n; i ++ )
    34. for (int j = 1; j <= m; j ++ )
    35. cin >> mp[i][j];
    36. for (int i = 1; i <= n; i ++ )
    37. for (int j = 1; j <= m; j ++ )
    38. ans = max(ans, dfs(i, j));
    39. cout << ans << endl;
    40. }

     

  • 相关阅读:
    【云原生之Docker实战】容器的资源限制使用方法
    依概率收敛和依分布收敛(附一道例题)
    MySQL——Centos7下环境安装
    解决在Vue项目中无法在Internet Explorer中打开的问题
    Flink学习(七)-单词统计
    Javascript中改变函数内部this指向的方法:call()、apply()、bind()
    【SQL 中级语法 2】自连接的用法
    如何搭建一个网站 -- 搭建一个网站需要多少钱
    LED热仿真笔记
    [JAVAee]Spring使用注解来存储与获取Bean对象
  • 原文地址:https://blog.csdn.net/qq_61935738/article/details/126241127