1088题

来源:互联网 发布:uc监控软件 编辑:程序博客网 时间:2024/06/05 14:15
                                                                                   滑雪
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 38599 Accepted: 13630

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 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9

Sample Output

25
#include<stdio.h>
int a[105][105];
int b[105][105];
int m,n;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int f(int x,int y){
 int max=1,temp=0,i,j,k;
 if(b[x][y]==0){
  for(i=0;i<4;i++){//判断四个方向,即对四个方向深搜,注意一点 对四个方向深搜时x,y的值不能变。
    j=x+dir[i][0];
       k=y+dir[i][1];
    if(j<m&&k<n&&j>=0&&k>=0&&a[j][k]<a[x][y]){
           temp=f(j,k)+1;
        if(temp>max) max=temp;//取四个方向的最大长度
    }
  }
     b[x][y]=max;
 }  
    return b[x][y];  //每次返回的就是这一点的最大长度
}
int main()
{
   scanf("%d%d",&m,&n);
     for(int i=0;i<m;i++)
   for(int j=0;j<n;j++){
    b[i][j]=0;
       scanf("%d",&a[i][j]);
   }
  int mmm=0;
  for(int s=0;s<m;s++)
   for(int t=0;t<n;t++){//枚举每一个点 即对每个点进行深搜
       int ttt=f(s,t);
    if(ttt>mmm) mmm=ttt;//如果要大了就替换
   }
  printf("%d/n",mmm);
 return 0;
}
/*
动态规划思路:最大下降子序列。多判断的一点就是纵横坐标之差的绝对值小于等于1也就是他们必须相邻*/
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
//定义结构体,便于动态规划找最长下降子序列
struct node {
 int i, j,map;
}steps[10001];
int step[10001];//存下降子序列的长度
int cmp(const void *a,const void *b)
{
 struct node *c,*d;
 c=(struct node *)a;
 d=(struct node *)b;
 return d->map -c->map ;
}
int main()
{
 int i,j,R,C,count=0,max;
 scanf("%d%d",&R,&C);
 for(i=0;i<R;i++)
  for(j=0;j<C;j++)
  {
   steps[count].i=i;steps[count].j=j;
   scanf("%d",&steps[count++].map);
  }
 qsort(steps,count,sizeof(steps[0]),cmp);
 step[0]=1;
 //比一般的求最长下降子序列多了几个判定条件,横,纵坐标必须相邻问题
 for(i=1;i<count;i++){
  max=0;
  for(j=0;j<i;j++)
  {
   if((steps[i].map <steps[j].map) &&
    ((fabs(steps[i].i-steps[j].i)==1&&steps[i].j-steps[j].j==0)||
    (fabs(steps[i].j-steps[j].j)==1&&steps[i].i-steps[j].i==0))&&max<step[j])
    max=step[j];
  }
  step[i]=max+1;
 }
 max=0;
 for(i=0;i<count;i++)
  if(max<step[i])
   max=step[i];
 printf("%d/n",max);
 return 0;
}