滑雪

【问题描述】
滑雪是一项非常刺激的运动, 为了获得速度, 滑雪的区域必须向下倾斜, 而且当你滑到坡底,
你不得不再次走上坡或者等待升降机来载你。 给出一个由二维数组表示的滑雪区域, 数组的
数字代表各点的高度。请你找出这个区域中最长的滑坡。
下面是一个例子:
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 更长。事实上,这是最长的
一条滑坡。
【输入文件】
输入文件 skin .in 的第一行为两个数 R, C,表示滑雪区域的行数和列数(1≤R,C≤100) 。下
面是 R 行,每行有 C 个整数,表示高度 H(0≤H≤10000) 。
【输出文件】
输出文件 t ski.out 包括一行,只包含一个整数,表示滑雪区域中最长滑坡的长度,即经过的
点的数量最大值。
【样例输入】
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
【样例输出】
25

F[i][j]表示走到 i 行 j 列的最大长度
枚举从每一个点出发 f[i][j] = max(f[i][j],f[i + dx[k]][j + dy[k]] + 1) ,dx,dy 是方向数组。图
上不好递推,则采用搜索的形式,一定要记忆化。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,a[101][101],f[101][101],ans;
 7 int dp(int x,int y)
 8 {
 9   if (f[x][y]) return f[x][y];
10   if (x+1<=n&&a[x+1][y]<a[x][y])
11     f[x][y]=max(f[x][y],dp(x+1,y));
12 
13   if (x-1&&a[x-1][y]<a[x][y])
14     f[x][y]=max(f[x][y],dp(x-1,y));
15 
16   if (y+1<=m&&a[x][y+1]<a[x][y])
17     f[x][y]=max(f[x][y],dp(x,y+1));
18 
19   if (y-1&&a[x][y-1]<a[x][y])
20     f[x][y]=max(f[x][y],dp(x,y-1));
21     return ++f[x][y];
22 }
23 int main()
24 {int i,j;
25   cin>>n>>m;
26   for (i=1;i<=n;i++)
27     {
28       for (j=1;j<=m;j++)
29     scanf("%d",&a[i][j]);
30     }
31   for (i=1;i<=n;i++)
32     {
33       for (j=1;j<=m;j++)
34     {
35       ans=max(ans,dp(i,j));
36     }
37     }
38   cout<<ans;
39 }
原文地址:https://www.cnblogs.com/Y-E-T-I/p/7645374.html