当前位置: 代码迷 >> 综合 >> [openjudge-动态规划]滑雪
  详细解决方案

[openjudge-动态规划]滑雪

热度:100   发布时间:2023-10-22 22:38:07.0

题目描述

描述

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更长。事实上,这是最长的一条。

输入

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

输出

输出最长区域的长度。

样例输入

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

来源

Don’t know

思路

直接仿照摘花生这道题是不行的,因为有四个方向而另外一题只有两个方向因此要使用新的方法,即是将坐标与数字储存在结构体中排序然后判断这个连续数列的最长上升子序列即可。用的方法是将二维转化一维,将会简单许多。
注:本题坑点很多,特别是数组初始化的大小。

代码实现

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct skit
{int x,y,num;
}re[10005];
bool cmp(skit a,skit b)
{if(a.num<b.num)return true; return false;
}
int n,m,a[105][105],maxx,p,b[105][105];
int main()
{memset(a,-999,sizeof(a));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);re[++p].x=i;re[p].y=j;re[p].num=a[i][j];}sort(re+1,re+p+1,cmp);for(int i=1;i<=p;i++){int nx=re[i].x,ny=re[i].y;if(a[nx][ny]>a[nx-1][ny])b[nx][ny]=max(b[nx][ny],b[nx-1][ny]+1);if(a[nx][ny]>a[nx+1][ny])b[nx][ny]=max(b[nx][ny],b[nx+1][ny]+1);if(a[nx][ny]>a[nx][ny-1])b[nx][ny]=max(b[nx][ny],b[nx][ny-1]+1);if(a[nx][ny]>a[nx][ny+1])b[nx][ny]=max(b[nx][ny],b[nx][ny+1]+1);maxx=max(maxx,b[nx][ny]);}printf("%d\n",maxx+1);
}