您的位置:首页 > 其它

滑雪(动规例题)

2016-04-22 21:04 176 查看
题目大意:

指在一个r*c的矩阵里找一些连在一起的数的最长不下降子序列。

样例输入:

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

这道题很容易想到如果要求一个点的最长不下降子序列,只能从其上下左右四个方向得来——对于每个[i,j]点,只有可能从[i+x,j+y]得来,(x,y)=[(1,0),(-1,0),(0,1),(0,-1)]。然而要保证f[i+x,j+y]在f[i,j]点之前得出来,则需要对高度进行快排,并按高度的从矮到高依次来求值,最后输出r,c里面的最大f[i,j]。

f[i,j]:=min{f[i+x,j+y]+1}(a[i,j]>a[i+x,j+y])。

代码:

const
dx:array[1..4] of Longint=(-1,0,1,0);
dy:array[1..4] of Longint=(0,1,0,-1);
var
r,c,i,j,k,ans,x,y,w:Longint;
f,p:array[0..101,0..101] of Longint;
a:Array[0..10000,1..3] of Longint;
procedure sort(l,r:Longint);
var
i,j,mid,p:longint;
begin
i:=l; j:=r;
mid:=a[(l+r) div 2,1];
while i<j do
begin
while a[i,1]<mid do inc(i);
while a[j,1]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
inc(i); dec(j);
end;
end;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;

begin
readln(r,c);
fillchar(p,sizeof(p),5);
for i:=1 to r do
for j:=1 to c do
begin
read(k);
w:=(i-1)*c+j;
p[i,j]:=k;
a[w,1]:=k; a[w,2]:=i; a[w,3]:=j;
end;

sort(1,r*c);

for i:=1 to r*c do
for k:=1 to 4 do
begin
x:=a[i,2]; y:=a[i,3];
if (p[x,y]>p[x+dx[k],y+dy[k]]) and (f[x,y]<f[x+dx[k],y+dy[k]]+1) then
f[x,y]:=f[x+dx[k],y+dy[k]]+1
end;
for i:=1 to r do
for j:=1 to c do
if f[i,j]>ans then ans:=f[i,j];
writeln(ans+1);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: