134.滑雪(动态规划--记忆化搜索)

2152 滑雪

 

 时间限制: 1 s
 空间限制: 32000 KB
 题目等级 : 黄金 Gold
题目描述 Description

trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。

输入描述 Input Description

输入文件

第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。

输出描述 Output Description

输出文件

仅一行: 输出1个整数,表示可以滑行的最大长度。

样例输入 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

数据范围及提示 Data Size & Hint

1s

代码:

#include< cstdio >

#include< iostream >

using namespace std;

#define INFn 1001

int step[INFn][INFn],high[INFn][INFn];

bool visit[INFn][INFn];

#include< cstring >

int r,c;

int xx[]={1,-1,0,0};

int yy[]={0,0,1,-1};

int maxx=-9999;

void input()

{

scanf("%d%d",&r,&c);

for(int i=1;i<=r;++i)

 for(int j=1;j<=c;++j)

 {

  scanf("%d",&high[i][j]);

  step[i][j]=1;

 }

}

int dfs(int i,int j)

{

if(visit[i][j]) return step[i][j];//如果当前这个点已经被更新过了,就不用再更新了 

int man=0;//否则的话,就把他更新一遍 

for(int k=0;k<4;++k)

{

        int x1=i+xx[k],y1=j+yy[k];

        if(x1>=1&&x1<=r&&y1>=1&&y1<=c&&high[i][j]>high[x1][y1])

        man=max(man,dfs(x1,y1));

}

step[i][j]=max(man+1,step[i][j]);//取最大值的原因是可能在递归中,会加多次 

visit[i][j]=true;//设置标志位 

return step[i][j];

}

void DFS()

{

memset(visit,false,sizeof(visit));

for(int i=1;i<=r;++i)

      for(int j=1;j<=c;++j)

      {

      int man=0;

      for(int k=0;k<4;++k)

       {

        int x1=i+xx[k],y1=j+yy[k];

        if(x1>=1&&x1<=r&&y1>=1&&y1<=c&&high[i][j]>high[x1][y1])

        man=max(man,dfs(x1,y1));//找出四条方向上的最大值 

}

step[i][j]=max(man+1,step[i][j]);//更新当前步数的最大值 

maxx=max(step[i][j],maxx);//更新最长路径 

visit[i][j]=true;//设为更新过了 

 }

}

int main()

{

input();

DFS();

printf("%d ",maxx);

return 0;

 

原文地址:https://www.cnblogs.com/c1299401227/p/5370680.html