NOIP前夕:noi.openjudge,滑雪

滑雪
总Time Limit: 1000msMemory Limit: 65536kB
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 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
Sample Output   25

记忆化搜索+dp
能够得到状态转移方程f[i,j]=min(f[i-1,j],f[i,j-1],f[i+1,j],f[i,j+1])+1
{high[x,y]>f[i,j]}
对每一个点都进行记忆化搜索,
记忆化搜索的优点就在于不会重复搜索
额,主要就这些吧。。。。

code:
var r,c,n:longint;
    init:array[1..100,1..100]of longint;
    i,j,k:longint;
    f:array[1..100,1..100]of longint;
    sx,sy:longint;
    used:array[1..100,1..100]of boolean;
    max,ans:longint;

procedure judge(i,j:longint);
          var max:longint;
          begin max:=0;
                if (i-1>=1)and(init[i-1,j]<init[i,j])
                   and(f[i,j]<f[i-1,j]+1)
                   then f[i,j]:=f[i-1,j]+1;
                if (i+1<=r)and(init[i+1,j]<init[i,j])
                   and(f[i,j]<f[i+1,j]+1)
                   then f[i,j]:=f[i+1,j]+1;
                if (j-1>=1)and(init[i,j-1]<init[i,j])
                   and(f[i,j]<f[i,j-1]+1)
                   then f[i,j]:=f[i,j-1]+1;
                if (j+1<=c)and(init[i,j+1]<init[i,j])
                   and(f[i,j]<f[i,j+1]+1)
                   then f[i,j]:=f[i,j+1]+1;
                if max<f[i,j]
                   then max:=f[i,j];
          end;

procedure dfs(x,y:longint);
          var i,j,k:longint;
          begin if f[x,y]<>0
                   then exit;
                k:=0;
                if (x-1>=1)and(init[x-1,y]<init[x,y])and
                   (used[x-1,y])
                   then begin inc(k);
                              used[x-1,y]:=false;
                              dfs(x-1,y);
                              judge(x-1,y);
                        end;
                if (x+1<=r)and(init[x+1,y]<init[x,y])and
                   (used[x+1,y])
                   then begin inc(k);
                              used[x+1,y]:=false;
                              dfs(x+1,y);
                              judge(x+1,y);
                        end;
                if (y-1>=1)and(init[x,y-1]<init[x,y])and
                   (used[x,y-1])
                   then begin inc(k);
                              used[x,y-1]:=false;
                              dfs(x,y-1);
                              judge(x,y-1);
                        end;
                if (y+1<=c)and(init[x,y+1]<init[x,y])and
                   (used[x,y+1])
                   then begin inc(k);
                              used[x,y+1]:=false;
                              dfs(x,y+1);
                              judge(x,y+1);
                        end;
                if k=0
                   then begin f[x,y]:=1;
                              exit;
                        end;
          end;

begin readln(r,c);
      for i:=1 to r do
          for j:=1 to c do
              read(init[i,j]);
      max:=0;
      for i:=1 to r do
          for j:=1 to c do
              begin sx:=i;
                    sy:=j;
                    fillchar(used,sizeof(used),true);
                    used[i,j]:=false;
                    dfs(i,j);

                    if (i-1>=1)and(init[i-1,j]<init[i,j])
                       and(f[i,j]<f[i-1,j]+1)
                       then f[i,j]:=f[i-1,j]+1;
                    if (i+1<=r)and(init[i+1,j]<init[i,j])
                       and(f[i,j]<f[i+1,j]+1)
                       then f[i,j]:=f[i+1,j]+1;
                    if (j-1>=1)and(init[i,j-1]<init[i,j])
                       and(f[i,j]<f[i,j-1]+1)
                       then f[i,j]:=f[i,j-1]+1;
                    if (j+1<=c)and(init[i,j+1]<init[i,j])
                       and(f[i,j]<f[i,j+1]+1)
                       then f[i,j]:=f[i,j+1]+1;

                    if max<f[i,j]
                       then max:=f[i,j];
              end;
      writeln(max);
end.





posted @ 2015-11-01 19:06  紫蜘蛛之歌  阅读(213)  评论(0编辑  收藏  举报