1088:滑雪
总时间限制: 1000ms 内存限制: 65536kB
描述
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<algorithm>
using namespace std;
int a[105][105];
int v[105][105];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
struct node
{
int x,y,num;
}value[10000];
bool cmp(struct node a1,struct node a2)
{
return a1.num<a2.num;
}
int main()
{
int r,c,k=1,maxv=0;
cin>>r>>c;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
v[i][j]=1;//初始化每个点可滑行长度为1
cin>>a[i][j];
value[k++]={i,j,a[i][j]};
}
sort(value+1,value+r*c+1,cmp);//按照高度从小到大排序
for(int i=1;i<=r*c;i++)
for(int j=0;j<=3;j++)//查看四周是否有比其低的点
{
int cx=dx[j]+value[i].x;
int cy=dy[j]+value[i].y;
if(cx>=1&&cx<=r&&cy>=1&&cy<=c&&value[i].num>a[cx][cy])
v[value[i].x][value[i].y]=max(v[value[i].x][value[i].y],v[cx][cy]+1);
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
maxv=max(v[i][j],maxv);
cout<<maxv;
return 0;
}```