zoukankan      html  css  js  c++  java
  • 滑雪(dfs+dp)

    滑雪
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 113903   Accepted: 43478

    Description

    Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 
     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

    一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

    Input

    输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

    Output

    输出最长区域的长度。

    Sample Input

    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
    

    Sample Output

    25

    show the codes:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn = 105;
    int n,m;
    int dp[maxn][maxn];
    int maze[maxn][maxn];
    int dir[4][2] = {{1,0},{-1,0},{0,-1},{0,1}};   // 二维方向数组的一种广义表形式表示方法!
     
    bool judge(int x,int y)   
    {
        if(x < 1 || x > n || y < 1 || y > m)
            return false;
        return true;
    }
     
    int dfs(int i,int j)     
    {
        if(dp[i][j])         
            return dp[i][j];
        int ret = 1;
        for(int k = 0; k < 4; k++)
        {
            int xx = i + dir[k][0];
            int yy = j + dir[k][1];
            if(judge(xx,yy) && maze[i][j] > maze[xx][yy])  
                ret = max(dfs(xx,yy)+1, ret);   
        }
        dp[i][j] = ret;   
        return ret;
    }
     
    int main()
    {
        while(scanf("%d %d", &n, &m) != EOF)
        {
            memset(dp,0,sizeof(dp));
            memset(maze,0,sizeof(maze));
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= m; j++)
                    scanf("%d", &maze[i][j]);
            int ans = 0;
            for(int i = 1;  i <= n; i++)
                for(int j = 1; j <= m; j++)
                    ans = max(dfs(i,j), ans);
            printf("%d
    ", ans);
        }
        return 0;
    }
    细节讨论:
    1.关于二维方向数组的表现形式:

    int dir[4][2]={{1,0},{-1,0},(0,1},{0,-1}};

    2.深度优先搜索(Depth-First-Search,简称DFS)。这是一种常见的用于遍历或搜索树或者图的算法。
    基本实现思想:
    (1)访问(visit)顶点v;
    (2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;
    (3)重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。
    3.强烈推荐(安利)优秀博文以了解dfs:
    https://blog.csdn.net/liangzhaoyang1/article/details/51415719
    十分感谢此博文以解决滑雪此题:
    https://blog.csdn.net/chen_ze_hua/article/details/51259888
    ---------------------------------------------------------------人的梦想,是不会终止的!
  • 相关阅读:
    数学(动态规划,GCD):COGS 469. [NOI2010]能量采集
    网络流(二分):BZOJ 3993: [SDOI2015]星际战争
    分治(CDQ):[BOI2007]摩基亚Mokia
    树状数组(二维):COGS 1532 [IOI2001]移动电话
    斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
    树形结构的维护:BZOJ 3991: [SDOI2015]寻宝游戏
    贪心 uvaoj 11134 Fabled Rooks
    动态规划(模型转换):uvaoj 1625 Color Length
    贪心 BZOJ 3671:[Noi2014]随机数生成器
    字符串(后缀数组):POJ 3415 Common Substrings
  • 原文地址:https://www.cnblogs.com/dragondragon/p/11250145.html
Copyright © 2011-2022 走看看