首先不难想到排序,这种无规律的东西一般都要转化为有规律才好做

首先以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)

显然这个是很容易用斜率优化的,不多说了

 var q,st:array[..] of longint;
    x,y,f:array[..] of int64;
    w,n,t,h,r,i:longint; procedure swap(var a,b:int64);
  var c:longint;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure sort(l,r: longint);
  var i,j: longint;
      p,q:int64;
  begin
    i:=l;
    j:=r;
    p:=x[(l+r) shr ];
    q:=y[(l+r) shr ];
    repeat
      while (x[i]<p) or (x[i]=p) and (y[i]<q) do inc(i);
      while (p<x[j]) or (p=x[j]) and (q<y[j]) do dec(j);
      if not(i>j) then
      begin
        swap(x[i],x[j]);
        swap(y[i],y[j]);
        inc(i);
        j:=j-;
      end;
    until i>j;
    if l<j then sort(l,j);
    if i<r then sort(i,r);
  end; function check(l,r:longint):double;
  begin
    check:=(f[l]-f[r])/(y[st[r+]]-y[st[l+]]);
  end; begin
  readln(n);
  for i:= to n do
    readln(x[i],y[i]);
  sort(,n);
  t:=;
  st[]:=;
  for i:= to n do
  begin
    while (t>) and (x[i]>=x[st[t]]) and (y[i]>=y[st[t]]) do dec(t);
    inc(t);
    st[t]:=i;
  end;
  f[]:=;
  r:=;
  h:=;
  for i:= to t do
  begin
    while (h<r) and (check(q[h+],q[h])<=x[st[i]]) do inc(h);
    w:=q[h];
    f[i]:=f[w]+y[st[w+]]*x[st[i]];
    while (h<r) and (check(i,q[r])<check(q[r],q[r-])) do dec(r);
    inc(r);
    q[r]:=i;
  end;
  writeln(f[t]);
end.
05-04 12:07