您的位置:首页 > 其它

bzoj1293: [SCOI2009]生日礼物

2017-04-17 08:27 176 查看
传送门

枚举起点找出每一种颜色在这个位置之后的第一个位置与这个位置距离的最大值,再找出每一个起点结果的最小值

转移时将当前节点坐标转移到下一个有这个颜色的位置。

可以用堆或者这个是叫做单调队列么?

uses math;
var
a:array [0..1000006] of longint;
p,h,l:array [0..65] of longint;
n,m,i,j,k,ma,mi,ans:longint;
procedure kp(l,r:longint);
var i,j,m,t:longint;
begin
i:=l; j:=r; m:=a[(l+r) div 2];
while (i<=j) do begin
while (a[i]<m) and (i<=r) do inc(i);
while (a[j]>m) and (j>=l) do dec(j);
if (i<=j) then begin
t:=a[i]; a[i]:=a[j]; a[j]:=t;
inc(i); dec(j);
end; end;
if (l<j) then kp(l,j);
if (i<r) then kp(i,r);
end;
begin
read(n,m);
for i:=1 to m do begin
read(l[i]); h[i]:=h[i-1]+l[i-1];
for j:=h[i] to h[i]+l[i]-1 do read(a[j]);
end;
p:=h; p[m+1]:=n+1;
ma:=0; mi:=maxlongint;
for i:=1 to m do begin
if (a[h[i]]>ma) then ma:=a[h[i]];
if (a[h[i]]<mi) then mi:=a[h[i]];
end;
ans:=ma-mi;
for i:=1 to n-m do
begin
k:=0;
for j:=1 to m do
if (h[j]+1<>p[j+1]) then
if (k=0) or (a[h[j]]<a[h[k]]) or ((a[h[j]]=a[h[k]]) and (a[h[j]+1]<a[h[k]+1])) then k:=j;
inc(h[k]);
ma:=0; mi:=maxlongint;
for j:=1 to m do begin
if (a[h[j]]>ma) then ma:=a[h[j]];
if (a[h[j]]<mi) then mi:=a[h[j]];
end;
ans:=min(ans,ma-mi);
end;
write(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: