土地租用加强版
题目描述
随着YYHS的OI集训队人数急剧增加,原有的小机房已经容纳不了数量庞大的队员。
于是史老师决定租用一些实验室机位供队员们训练,他正在考虑为N (1 <= N <= 50,000)位队员租用机位。实验室管理员根据要求给出了N个机位的长和宽,每个机位的长宽满足(1 <= 宽 <= 1,000,000; 1 <= 长 <= 1,000,000).
而机位的租用价格是它的面积,实验室管理员也提出,可以同时租用多个机位. 租用这一组机位的价格是它们最大的长乘以它们最大的宽, 但是机位的长宽不能交换. 如果想租下一个3x5的机位和一个5x3的机位,则他需要付5x5=25.
于是问题出现了,史老师希望租下所有的机位,但是他发现分组来租这些机位可以节省经费. 他需要你帮助他找到最小的经费.
输入
- 第1行: 一个数: N
- 第2..N+1行: 每行包含两个数,分别为机位的长和宽
输出
- 第一行: 最小的可行费用.
样例输入
4
100 1
15 15
20 5
1 100
样例输出
500
提示
分3组租用这些机位: 第一组:100x1, 第二组1x100, 第三组20x5 和 15x15. 每组的价格分别为100,100,300, 总共500.
50:
var
oo,i,j,k,n,m,maxi:longint;
max:int64;
a,b,f:array [1..1000000] of int64;
function min(a,b:int64):int64;
begin
if a<b then exit(a)
else exit(b);
end;
procedure qsort(l,r:longint);
var
i,j:longint;
mid,t,mid1:int64;
begin
i:=l; j:=r;
mid:=a[(l+r) div 2];
mid1:=b[(l+r) div 2];
while i<=j do
begin
while (a[i]<mid) or
(a[i]=mid) and (b[i]<mid1) do inc(i);
while (a[j]>mid) or
(a[j]=mid) and (b[j]>mid1)do dec(j);
if i<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
t:=b[i];b[i]:=b[j];b[j]:=t;
inc(i); dec(j);
end;
end;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
begin
oo:=1000000000;
readln(n);
for i:=1 to n do read(a[i],b[i]);
qsort(1,n);
for i:=1 to n do
begin
f[i]:=oo;
for j:=0 to i-1 do
begin
max:=0;
maxi:=0;
for k:=j+1 to i do
begin
if b[k]>max then begin max:=b[k];maxi:=k;end;
end;
f[i]:=min(f[i],f[j]+a[i]*b[maxi]);
end;
end;
writeln(f[n]);
end.
100:
var
n,u1,u2,gs,l,r:longint;
a,b,q:array[0..50000]of longint;
f:array[0..50000]of int64;
procedure sweap(x,y:longint);
var c:longint;
begin
c:=a[x];a[x]:=a[y];a[y]:=c;
c:=b[x];b[x]:=b[y];b[y]:=c;
end;
procedure qsort(x,y:longint);
var
l,r,f,k:longint;
begin
l:=x;r:=y;
f:=a[(x+y)>>1];
k:=b[(x+y)>>1];
repeat
while (a[l]<f) or ((a[l]=f) and (b[l]<k))do inc(l);
while (a[r]>f) or ((a[r]=f) and (b[r]>k))do dec(r);
if l<=r then
begin
sweap(l,r);
inc(l);
dec(r);
end;
until l>r;
if l<y then qsort(l,y);
if x<r then qsort(x,r);
end;
function slope(i,j:longint):real;
begin
if b[j+1]=b[i+1] then
if f[i]>=f[j] then exit(maxlongint)
else exit(-maxlongint);
exit((f[i]-f[j])/(b[j+1]-b[i+1]));
end;
begin
readln(n);for u1:=1 to n do read(a[u1],b[u1]);
qsort(1,n);
for u1:=1 to n do
begin
while(gs>0) and (a[gs]<=a[u1]) and (b[gs]<=b[u1]) do dec(gs);
inc(gs);
a[gs]:=a[u1];
b[gs]:=b[u1];
end;
for u1:=1 to gs do
begin
while (l<r) and (a[u1]>=slope(q[l],q[l+1])) do inc(l);
f[u1]:=f[q[l]]+int64(a[u1])*b[q[l]+1];
while (l<r) and (slope(q[r-1],q[r])>slope(q[r],u1))do dec(r);
inc(r);q[r]:=u1;
end;
writeln(f[gs]);
end.