代码改变世界

滑雪

2010-10-15 21:06  snowkylin  阅读(195)  评论(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。

输出格式

输出最长区域的长度。

样例输入

样例输出

program Project1;
type node=record
                        x,y:longint;
                        data:longint;
                        end;
var a:array[1..100,1..100]of node;
    b:array[1..10000]of node;
    f:array[0..101,0..101]of longint;
    r,c,i,j,max,maxn,temp,k:longint;
    t:node;
begin
     readln(r,c);
     k:=0;
     for i:=1 to r do
         for j:=1 to c do with a[i,j] do begin read(a[i,j].data);x:=i;y:=j;inc(k);b[k]:=a[i,j] end;
     for i:=1 to r*c-1 do
         for j:=i to r*c do
             if b[i].data>b[j].data then begin t:=b[i];b[i]:=b[j];b[j]:=t; end;
     fillchar(f,sizeof(f),0);
     for i:=0 to c+1 do begin f[0,i]:=-1;f[r+1,i]:=-1; end;
     for i:=0 to r+1 do begin f[i,0]:=-1;f[i,c+1]:=-1; end;
     for i:=1 to r*c do
     begin
          max:=0;
          with b[i] do
          begin
               if (f[x+1,y]>max)and(a[x,y].data>a[x+1,y].data) then max:=f[x+1,y];
               if (f[x-1,y]>max)and(a[x,y].data>a[x-1,y].data) then max:=f[x-1,y];
               if (f[x,y+1]>max)and(a[x,y].data>a[x,y+1].data) then max:=f[x,y+1];
               if (f[x,y-1]>max)and(a[x,y].data>a[x,y-1].data) then max:=f[x,y-1];
               f[x,y]:=max+1;
          end;
     end;
     max:=0;
     for i:=1 to r do
         for j:=1 to c do
         if f[i,j]>max then max:=f[i,j];
     writeln(max);
end.   

 

记录下每个点的坐标,然后对高度进行排序。
很容易的想到:对于高度为k的点的能够成的最长的路径,一定是与它相邻4个点中高度小于k的点 中的最优值加上1,(边界:若相邻点中没有点比它低,那么它的值则为1)。
按照点的高度从低到高进行DP即可...