vijos-p1011 2008.11.7
背景 Background
顺治帝福临,是清朝入关后的第一位皇帝。他是皇太极的第九子,生于崇德三年(1638)崇德八年八月二ten+six日在沈阳即位,改元顺治,在位18年。卒于顺治十八年(1661),终24岁。
顺治即位后,由叔父多尔衮辅政。顺治七年,多尔衮出塞射猎,死于塞外。14岁的福临提前亲政。顺治帝天资聪颖,读书勤奋,他吸收先进的汉文化,审时度势,对成法祖制有所更张,且不顾满洲亲贵大臣的反对,倚重汉官。为了使新兴的统治基业长治久安,他以明之兴亡为借鉴,警惕宦官朋党为祸,重视整饬吏治,注意与民休息,取之有节。但他少年气盛,刚愎自用,急噪易怒,当他宠爱的董妃去世后,转而消极厌世,终于匆匆走完短暂的人生历程,英年早逝。他是清朝历史上唯一公开归依禅门的皇帝。
描述Description
顺治喜欢滑雪,这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待太监们来载你。顺治想知道载一个区域中最长的滑坡。
区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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 Format
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 500)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
输出格式 Output Format
输出最长区域的长度。
样例输入 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
最长xx序列
program 1--搜索过5组
program p_1011;
const fin='in.in';fout='out.out';
var a:array[1..500,1..500]of longint;
f:array[1..500,1..500]of boolean;
f1,f2:text;
c,r,i,j,max:longint;
procedure deal(x,y,t:longint);
begin
if t>max then max:=t;
if (x-1>0)and(f[x-1,y])and(a[x-1,y]<a[x,y]) then
begin f[x-1,y]:=false;deal(x-1,y,t+1);
f[x-1,y]:=true;end;
if (x+1<=c)and(f[x+1,y])and(a[x+1,y]<a[x,y])then
begin f[x+1,y]:=false;deal(x+1,y,t+1);
f[x+1,y]:=true;end;
if (y-1>0)and(f[x,y-1])and(a[x,y-1]<a[x,y]) then
begin f[x,y-1]:=false;deal(x,y-1,t+1);
f[x,y-1]:=true;end;
if (y+1<=r)and(f[x,y+1])and(a[x,y+1]<a[x,y]) then
begin f[x,y+1]:=false;deal(x,y+1,t+1);
f[x,y+1]:=true;end;
end;
begin
{ assign(f1,fin);reset(f1);
assign(f2,fout);rewrite(f2);}
read(c,r);
for i:=1 to c do
for j:=1 to r do read(a[i,j]);
fillchar(f,sizeof(f),true);
max:=0;
for i:=1 to c do
for j:=1 to r do
begin
fillchar(f,sizeof(f),true);
f[i,j]:=false;
deal(i,j,1);
end;
writeln(max);
end.
Program 2--dp+堆,仍然过3组
program p_1011;
var c1,r,i,j,max,tt,lc:longint;
a,b,f,c:array[1..25000]of longint;
procedure sift(l,m:longint);
var i,j, t:longint;
begin
i:=l;j:=2*i;t:=b[i];
while j<=m do
begin
if (j<m) and (a[b[j]]>a[b[j+1]]) then inc(j);
if a[t]>a[b[j]] then
begin b[i]:=b[j];i:=j;j:=2*i; end
else exit;
b[i]:=t;
end;
end;
procedure init;
var i:longint;
begin read(c1,r);tt:=c1*r;
for i:=1 to tt do
begin
read(a[i]);b[i]:=i;
end;
for i:=(tt div 2) downto 1 do
sift(i,tt);lc:=0;
for i:=tt downto 2 do
begin
inc(lc);c[lc]:=b[1];
b[1]:=b[i];
sift(1,i-1);
end;
inc(lc);c[lc]:=b[1];
max:=0;
end;
procedure dp;
var i,i1:longint;
begin
fillchar(f,sizeof(f),0);
for i:=1 to tt do
begin i1:=c[i];
if (i1-r>0)and(a[i1]>a[i1-r])and(f[i1-r]>f[i1]) then f[i1]:=f[i1-r];
if (i1+r<tt)and(a[i1]>a[i1+r])and(f[i1+r]>f[i1]) then f[i1]:=f[i1+r];
if (i1 mod r<>1)and(a[i1]>a[i1-1])and(f[i1-1]>f[i1]) then f[i1]:=f[i1-1];
if (i1 mod r<>0)and(a[i1]>a[i1+1])and(f[i1+1]>f[i1]) then f[i1]:=f[i1+1];
inc(f[i1]);if f[i1]>max then max:=f[i1];
end;
end;
begin
init;
dp;
writeln(max);
end.
Program 3: p+qsort
过
3
组,但时间很短,只是有个错误号错误号
-1073741571---
栈溢出
program p_1011;
var c,r,i,j,max,tt:longint;
a,b,f:array[1..25000]of longint;
procedure qsort(i1,j1:longint);
var
l1,r1,x1,y1:longint;
begin
l1:=i1;r1:=j1;
x1:=a[b[(l1+r1) div 2]];
repeat
while a[b[l1]]<x1 do inc(l1);
while a[b[r1]]>x1 do dec(r1);
if l1<=r1 then
begin
y1:=b[l1];
b[l1]:=b[r1];
b[r1]:=y1;
inc(l1);
dec(r1);
end;
until l1>r1;
if r1>i1 then qsort(i1,r1);
if l1<j1 then qsort(l1,j1);
end;
procedure init;
var i:longint;
begin read(c,r);tt:=c*r;
for i:=1 to tt do
begin
read(a[i]);b[i]:=i;
end;
qsort(1,tt);
max:=0;
end;
procedure dp;
var i,i1:longint;
begin
fillchar(f,sizeof(f),0);
for i:=1 to tt do
begin i1:=b[i];
if (i1-r>0)and(a[i1]>a[i1-r])and(f[i1-r]>f[i1]) then f[i1]:=f[i1-r];
if (i1+r<tt)and(a[i1]>a[i1+r])and(f[i1+r]>f[i1]) then f[i1]:=f[i1+r];
if (i1 mod r<>1)and(a[i1]>a[i1-1])and(f[i1-1]>f[i1]) then f[i1]:=f[i1-1];
if (i1 mod r<>0)and(a[i1]>a[i1+1])and(f[i1+1]>f[i1]) then f[i1]:=f[i1+1];
inc(f[i1]);if f[i1]>max then max:=f[i1];
end;
end;
begin
init;
dp;
writeln(max);
end.
Program 3:很强悍的数据结构处理
{qsort+dp}
program asdf;
type rec=record
x,y,dat:longint;
end;
var
r,c,i,j,ans:longint;
inf:array[0..250000]of rec;
nea:array[1..250000,1..4]of longint;
f:array[0..250000]of longint;
a:array[0..501,0..501]of longint;
procedure sort(l,r:longint);
var
i,j,m:longint;
begin
i:=l;j:=r;
m:=inf[(l+r)div 2].dat;
while i<j do
begin
while inf[i].dat>m do i:=i+1;
while inf[j].dat<m do j:=j-1;
if i<=j then
begin
a[inf[i].x,inf[i].y]:=j;a[inf[j].x,inf[j].y]:=i;
inf[0]:=inf[i];inf[i]:=inf[j];inf[j]:=inf[0];
i:=i+1;j:=j-1;
end;
end;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
begin
readln(r,c);
for i:=1 to r do
begin
for j:=1 to c do read(a[i,j]);
readln;
end;
for i:=1 to r do
for j:=1 to c do
begin
inf[(i-1)*c+j].dat:=a[i,j];
inf[(i-1)*c+j].x:=i;
inf[(i-1)*c+j].y:=j;
a[i,j]:=(i-1)*c+j;//把矩阵转换成线性表,并在矩阵忠存下在线性表中的标号
end;
sort(1,r*c);
for i:=1 to r*c do
begin
nea[i,1]:=a[inf[i].x,inf[i].y-1];
nea[i,2]:=a[inf[i].x-1,inf[i].y];
nea[i,3]:=a[inf[i].x,inf[i].y+1];
nea[i,4]:=a[inf[i].x+1,inf[i].y];
end;//每个点四个方向相邻的格子在线性表中的标号
for i:=1 to r*c do f[i]:=1;//初始化
ans:=1;
for i:=2 to r*c do
begin
for j:=1 to 4 do//最长xx序列
if (f[nea[i,j]]+1>f[i])and(inf[nea[i,j]].dat>inf[i].dat) then
begin
f[i]:=f[nea[i,j]]+1;
end;
if f[i]>ans then ans:=f[i];
end;
writeln(ans);
end.