poj 1088 滑雪 ( 记忆化搜索 )

滑雪
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 67020   Accepted: 24632

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


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define maxn 105
using namespace std;

int n,m,ans,ma;
int mp[maxn][maxn];
int dp[maxn][maxn];                    // 用dp数组将搜索结果存起来  实现记忆化
int vis[maxn][maxn];
int sta[maxn*maxn];
int dx[4]= {-1,1,0,0};
int dy[4]= {0,0,-1,1};

int dfs(int x,int y)
{
    if(dp[x][y]) return dp[x][y];      // 记忆化  如果已经搜过 就不再搜了
    int i,nx,ny,temp,ma=0;
    for(i=0;i<4;i++)
    {
        nx=x+dx[i];
        ny=y+dy[i];
        if(mp[nx][ny]<mp[x][y])
        {
            temp=dfs(nx,ny);
            if(ma<temp) ma=temp;
        }
    }
    dp[x][y]=ma+1;           // 加上自己
    return dp[x][y];
}
int main()
{
    int i,j,t;
    while(~scanf("%d%d",&n,&m))
    {
        memset(mp,0x3f,sizeof(mp));
        memset(dp,0,sizeof(dp));
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                scanf("%d",&mp[i][j]);
            }
        }
        ans=0;
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                t=dfs(i,j);
                if(ans<t) ans=t;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}






你可能感兴趣的:(poj 1088 滑雪 ( 记忆化搜索 ))