首先不难想到排序,这种无规律的东西一般都要转化为有规律才好做
首先以x为第一关键字,y为第二关键字升序排序
拍完序我们发现,若存在两块土地i,j
x[i]<=x[j],y[i]<=y[j],那么土地i的购买一定可以忽略(因为价格是由x,y的乘积决定的)
剔除掉不需考虑的土地,不难发现剩下的土地x是升序而y是降序的
然后就可以dp了
f[i]=min(f[k]+x[i]*y[k+1]); (0<=k<=i-1)
显然这个是很容易用斜率优化的,不多说了
1 var q,st:array[0..50010] of longint; 2 x,y,f:array[0..50010] of int64; 3 w,n,t,h,r,i:longint; 4 5 procedure swap(var a,b:int64); 6 var c:longint; 7 begin 8 c:=a; 9 a:=b; 10 b:=c; 11 end; 12 13 procedure sort(l,r: longint); 14 var i,j: longint; 15 p,q:int64; 16 begin 17 i:=l; 18 j:=r; 19 p:=x[(l+r) shr 1]; 20 q:=y[(l+r) shr 1]; 21 repeat 22 while (x[i]<p) or (x[i]=p) and (y[i]<q) do inc(i); 23 while (p<x[j]) or (p=x[j]) and (q<y[j]) do dec(j); 24 if not(i>j) then 25 begin 26 swap(x[i],x[j]); 27 swap(y[i],y[j]); 28 inc(i); 29 j:=j-1; 30 end; 31 until i>j; 32 if l<j then sort(l,j); 33 if i<r then sort(i,r); 34 end; 35 36 function check(l,r:longint):double; 37 begin 38 check:=(f[l]-f[r])/(y[st[r+1]]-y[st[l+1]]); 39 end; 40 41 begin 42 readln(n); 43 for i:=1 to n do 44 readln(x[i],y[i]); 45 sort(1,n); 46 t:=1; 47 st[1]:=1; 48 for i:=2 to n do 49 begin 50 while (t>0) and (x[i]>=x[st[t]]) and (y[i]>=y[st[t]]) do dec(t); 51 inc(t); 52 st[t]:=i; 53 end; 54 f[0]:=0; 55 r:=0; 56 h:=0; 57 for i:=1 to t do 58 begin 59 while (h<r) and (check(q[h+1],q[h])<=x[st[i]]) do inc(h); 60 w:=q[h]; 61 f[i]:=f[w]+y[st[w+1]]*x[st[i]]; 62 while (h<r) and (check(i,q[r])<check(q[r],q[r-1])) do dec(r); 63 inc(r); 64 q[r]:=i; 65 end; 66 writeln(f[t]); 67 end.