题目描述
输入
输出
样例输入
Sample Input1:
5
1 2 3 4 5
1 2 3 4 5
Sample Input2:
5
1 2 2 4 5
5 4 3 4 1
样例输出
Sample Output1:
15
19
22
24
25
Sample Output2:
12
17
21
24
27
数据范围限制
提示
思路:
先打个暴力(60分)
然后就会发现,如果当前已经走到最后一个了,那么接下来的推销顺序就已经确定了
我们可以快排一下,然后输出
这虽然是水法,但却很有意义……
(正解是线段树……某位大犇考场AC……)
代码:
var
n,i,j,k,x,y,z,s,ls:longint;
a:array[0..100001,1..2]of longint;
b:array[0..100001]of boolean;
procedure qs(l,r:longint);
var
i,j,x:longint;
y:array[1..2]of longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2,1];
repeat
while a[i,1]<x do inc(i);
while x<a[j,1] 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:longint;
y:array[1..2]of longint;
c:boolean;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2,2];
repeat
while a[i,2]>x do inc(i);
while x>a[j,2] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
c:=b[i];
b[i]:=b[j];
b[j]:=c;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs1(l,j);
if i<r then qs1(i,r);
end;
procedure qs2(l,r:longint);
var
i,j,x:longint;
y:array[1..2]of longint;
c:boolean;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2,2];
repeat
while a[i,2]<x do inc(i);
while x<a[j,2] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
c:=b[i];
b[i]:=b[j];
b[j]:=c;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs2(l,j);
if i<r then qs2(i,r);
end;
begin
assign(input,'salesman.in');
reset(input);
assign(output,'salesman.out');
rewrite(output);
readln(n);
for i:=1 to n do
read(a[i,1]);
for i:=1 to n do
read(a[i,2]);
qs(1,n);
for i:=1 to n do
if ls<>a[i,1] then
begin
if i<>1 then qs2(x,i-1);
x:=i;
ls:=a[i,1];
end;
qs2(x,n);
ls:=0;
x:=0;
for i:=1 to n do
begin
for j:=1 to n do
if b[j]=false then
begin
z:=0;
if ls<j then z:=(a[j,1]-a[ls,1])*2;
inc(z,a[j,2]);
if z>=x then
begin
y:=j;
x:=z;
end;
end;
b[y]:=true;
if ls<y then ls:=y;
inc(s,x);
writeln(s);
if ls=n then
begin
qs1(1,n);
for j:=1 to n do
if b[j]=false then
begin
inc(s,a[j,2]);
writeln(s);
end;
halt;
end;
x:=0;
end;
end.