zoukankan      html  css  js  c++  java
  • DFS:POJ1088-滑雪(记忆化搜索)

    题目:
    滑雪
    Time Limit: 1000MS

    Memory Limit: 65536K
    Total Submissions: 97666

    Accepted: 37055
    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
    Source
    SHTSC 2002







    解题心得:
    1、一开始在做这个题的时候是直接找的最高点然后到达最低点的最长路径,然后毫无疑问的wrong了,其实很容易看出可能出现多个相同的最高点。
    2、其实这个一个题记忆化搜索一下就行了,将每一个点当作起点,记录它到达其他点的最远的路径,如果到达这个点的路径小于已经记录下来的路径直接跳出就行了,为了优化,也可以先找一个最高点然后深搜一下,记录一下到达每个点的路径,如果其他起点小于这个点被记录的值就直接跳出。这样做的根据在于每一个点都只能走比它低的点,所以可以这样使用记忆话搜索。
    3、记忆化搜索可以看一下点击打开链接






    我的代码:
    #include<stdio.h>
    const int maxn = 110;
    int n,m;
    int dir[4][2]= {0,1,0,-1,1,0,-1,0};
    int start_x,start_y;
    int Max = 0;
    struct Maps
    {
        int num;
        int step;
    } maps[maxn][maxn];
    
    bool check(int x,int y)
    {
        if(x<0 || y<0 || x>=n || y>=m)
            return false;
        else
            return true;
    }
    void pre_maps()
    {
        Max = -1;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                scanf("%d",&maps[i][j].num);
                maps[i][j].step = 0;
                if(Max < maps[i][j].num)
                {
                    Max = maps[i][j].num;
                    start_x = i;
                    start_y = j;
                }
            }
        }
    }
    
    void dfs(int x,int y,int step)
    {
        if(step > Max)//直接用Max记录一下最远的路径就可以了
            Max = step;
        if(step < maps[x][y].step)
            return ;
        else
            maps[x][y].step = step;
        for(int i=0; i<4; i++)
        {
            if(check(x+dir[i][0],y+dir[i][1]) && (maps[x+dir[i][0]][y+dir[i][1]].num < maps[x][y].num))
            {
                dfs(x+dir[i][0],y+dir[i][1],step+1);
            }
        }
    }
    
    int main()
    {
    
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            pre_maps();
            Max = -1;
            dfs(start_x,start_y,1);//这一步主要是为了优化
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                {
                    dfs(i,j,1);
                }
            printf("%d
    ",Max);
        }
    }
    




  • 相关阅读:
    图片不能显示
    Lambda表达式where过滤数据
    存储文本到一个文件里
    获取用户临时文件夹路径
    判断某一个字符串是否存在另一个字符串中
    使用反射为特性赋值
    字符串与数据流之间的转换
    控制台应用程序获取计算机名
    重复输出字符或字符串
    使用HashSet<>去除重复元素的集合
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107355.html
Copyright © 2011-2022 走看看