题目描述
输入
输出
样例输入
样例输入1
3
1 4 5
2
3 8
样例输入2
3
3 1 10
2
8 3
样例输出
样例输出1
6
样例输出2
4
数据范围限制
提示
心路历程:
这题就是个DP
题目给了个提示,说要注意内存,我算了一下,时间和空间都超了
空间可以用滚动数组,But,时间呢?
后来讨论后,发现,原来当前状态的更新只来源于两个地方,于是AC!!
思路:
DP方程:F[i,j]=min(F[i,j-1],F[i-1,j-1])+abs(j树到i猴子的距离);
因为当前猴子只可能去当前树或前一棵树,DP就很好优化了!
代码:
uses math;
var
n,m,i,j,k,x,y,z,s,ls:longint;
a,b:array[0..5001]of int64;
f:array[0..1,0..5001]of int64;
procedure qs(l,r:longint);
var
i,j,x,y:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs(l,j);
if i<r then qs(i,r);
end;
procedure qs1(l,r:longint);
var
i,j,x,y:longint;
begin
i:=l;
j:=r;
x:=b[(l+r) div 2];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if not(i>j) then
begin
y:=b[i];
b[i]:=b[j];
b[j]:=y;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs1(l,j);
if i<r then qs1(i,r);
end;
begin
assign(input,'tree.in');
reset(input);
assign(output,'tree.out');
rewrite(output);
readln(n);
for i:=1 to n do
read(a[i]);
readln(m);
for i:=1 to m do
read(b[i]);
qs(1,n);
qs1(1,m);
x:=1;
fillchar(f,sizeof(f),127);
f[1,0]:=0;
for i:=1 to m do
begin
x:=1-x;
f[x,0]:=maxlongint;
for j:=1 to n do
begin
f[x,j]:=min(f[x,j-1]+abs(b[i]-a[j]),f[1-x,j-1]+abs(b[i]-a[j]));
end;
end;
writeln(f[x,n]);
end.