题目:滑雪 rqnoj317
题目描述
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。
输出格式
输出最长区域的长度。
样例输入
样例输出
这是基础动规的题,其实就是走迷宫的加强版,不过由于数据范围对深搜来说太大,所以只能用动规解决
如果递推的话拓扑序很难找,或者说不好找,于是就可用记忆化搜索来自动维护拓扑序
Pascal Code
program rqnoj317;
const
dx:array[1..4] of longint=(0,0,1,-1);
dy:array[1..4] of longint=(1,-1,0,0);
var
n,m:longint;
f,map:array[0..100+10,0..100+10] of longint;
procedure init;
begin
assign(input,'rqnoj317.in');
assign(output,'rqnoj317.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
halt;
end;
procedure readdata;
var
i,j:longint;
begin
read(n,m);
for i:=1 to n do
for j:=1 to m do
read(map[i,j]);
end;
function max(i,j:longint):longint;
var
k:longint;
begin
if (i<1)or(i>n)or(j<1)or(j>n) then exit(0);
if f[i,j]<>0 then exit(f[i,j]);
f[i,j]:=1;
for k:=1 to 4 do
begin
if (map[i,j]<map[i+dx[k],j+dy[k]])and(f[i,j]<max(i+dx[k],j+dy[k])+1) then
f[i,j]:=max(i+dx[k],j+dy[k])+1;
end;
exit(f[i,j]);
end;
procedure main;
var
best,i,j:longint;
begin
fillchar(f,sizeof(f),0);
best:=0;
for i:=1 to n do
for j:=1 to m do
if best<max(i,j) then best:=max(i,j);
writeln(best);
end;
begin
init;
readdata;
main;
outit;
end.