P1434 [SHOI2002]滑雪

题目描述

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

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

输入格式

输入的第一行为表示区域的二维数组的行数 R 和列数 C。下面是 R 行,每行有 C 个数,代表高度(两个数字之间用 1 个空格间隔)。

输出格式

输出区域中最长滑坡的长度。

输入输出样例

输入 #1
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
输出 #1
25

说明/提示

对于 100% 的数据,1R,C100。

分析

从第一个点开始遍历,将每个点能够滑行的最大距离存入一个数组里,以后如果再次经过这个点,就直接返回答案,最后找所有点中滑行距离最大的一个点。

 

这段代码不知道为什么在第二个点会tle,希望以后自己能搞懂。

```cpp
#include<iostream>
using namespace std;
#define N 111
int hi[N][N],anss[N][N];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int r,c,ans,sum,cnt;
void dfs(int x,int y,int z)
{
    if(anss[x][y])
    {
        sum+=anss[x][y];
        if(sum>cnt)
            cnt=sum;
        sum-=anss[x][y];
        return;
    }
    if(sum>cnt)cnt=sum;
    for(int i=0;i<4;++i)
    {
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>0&&yy>0&&xx<=r&&yy<=c&&hi[xx][yy]>z)
        {
            sum++;
            dfs(xx,yy,hi[xx][yy]);
            sum--;
        }
    }
    return;
}
int main()
{
    cin >> r >> c ;
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
            cin >> hi[i][j];
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
        {
            sum=cnt=0;
            dfs(i,j,hi[i][j]);
            if(cnt>ans) ans=cnt;
        }
    cout << ans + 1 << endl ;
    return 0;
}
```
TLE

AC代码

```cpp
#include<bits/stdc++.h>
using namespace std;
#define N 111
int hi[N][N],anss[N][N];
int dx[4]={1,-1,0,0};//移动方向
int dy[4]={0,0,1,-1};//同上
int r,c,ans,sum,cnt;
int dfs(int x,int y)
{
    if(anss[x][y]) return anss[x][y];//如果之前已经算过,直接返回答案
    anss[x][y]=1;//第一个点算在滑行距离内
    for(int i=0;i<4;++i)//改变方向寻找最大滑行距离
    {
        int xx=x+dx[i],yy=y+dy[i];//改变移动方向
        if(xx>0&&yy>0&&xx<=r&&yy<=c&&hi[xx][yy]>hi[x][y])//确保不会越界且向更低处滑行
        {
            dfs(xx,yy);
            if(anss[xx][yy]+1>anss[x][y])
                anss[x][y]=anss[xx][yy]+1;
        }
    }
    return anss[x][y];
}
int main()
{
    cin >> r >> c ;
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
            cin >> hi[i][j];
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
        {
            cnt=0;
            cnt=dfs(i,j);
            if(cnt>ans) ans=cnt;//寻找最大滑行距离
        }
    cout << ans << endl ;
    return 0;
}
```

 

posted @ 2020-12-15 17:11  屑魔女伊蕾娜  阅读(142)  评论(0)    收藏  举报