P2900 [USACO08MAR]土地購買Land Acquisition G
阿新 • • 發佈:2021-02-15
文章目錄
R e s u l t Result Result
H y p e r l i n k Hyperlink Hyperlink
https://www.luogu.com.cn/problem/P2900
D e s c r i p t i o n Description Description
有 n n n塊土地,第 i i i塊土地的長為 x i x_i xi,寬為 y i y_i yi ,現需將這些土地分成若干組,分成一組將產生這一組內長的最大值 × \times ×寬的最大值的代價,試確定一種分組方案,使得總代價最小
資料範圍: n ≤ 5 × 1 0 4 , x i , y i ≤ 1 0 6 n\leq 5\times 10^4,x_i,y_i\leq 10^6 n≤5×104,xi,yi≤106
S
o
l
u
t
i
o
n
Solution
Solution
將每個土地的長和寬抽象的看做是一個點 ( x , y ) (x,y) (x,y),注意到如果存在兩個點 A ( x , y ) , B ( x ‘ , y ‘ ) A(x,y),B(x^`,y^`) A(x,y),B(x‘,y‘)滿足 x ≤ x ‘ , y ≤ y ‘ x\leq x^`,y\leq y^` x≤x‘,y≤y‘,則 A A A這個點是可以捨棄的,因為顯然當且僅當把它和 B B B劃分到一起答案會更優。
如果我們把所有矩形按照 x x x為第一關鍵字升序排序,剩下來的點在第一象限中就構成了階梯型。
設
f
i
f_i
fi表示劃分到第
i
i
i個矩形的最優代價
可以證明或打表發現 f j f_j fj後面那坨滿足四邊形不等式,即 f f f具有決策單調性
如此,我們只需考慮每個決策對後續轉移的影響,然後二分出決策的賺一點即可
時間複雜度: O ( n log 2 n ) O(n\log_2 n) O(nlog2n)
C o d e Code Code
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define LL long long
#define N 50010
using namespace std;int n,m,tl,hd,maxl;
struct node{LL x,y;}a[N];
struct note{int l,r,x;}que[N];
inline bool cmp(node x,node y){return x.x<y.x||x.x==y.x&&x.y>y.y;}
LL f[N];
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline LL Cost(int i,int j){return f[i]+a[i+1].y*a[j].x;}
inline int findx(int i)
{
int L=que[tl].l,R=que[tl].r,mid;
while(L<=R)
{
mid=L+R>>1;
if(Cost(i,mid)<Cost(que[tl].x,mid)) R=mid-1;else L=mid+1;
}
return L;
}
signed main()
{
n=read();
for(register int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
sort(a+1,a+1+n,cmp);
for(register int i=1;i<=n;i++)
{
while(m&&a[m].y<=a[i].y) m--;
a[++m]=a[i];
}
que[hd=tl=1]=(note){1,m,0};
for(register int i=1;i<=m;i++)
{
while(hd<=tl&&que[hd].r<i) hd++;
f[i]=Cost(que[hd].x,i);
while(hd<=tl&&i<que[tl].l&&Cost(i,que[tl].l)<Cost(que[tl].x,que[tl].l)) tl--;
int u=findx(i);que[tl].r=u-1;
if(u<=m) que[++tl]=(note){u,m,i};
}
printf("%lld",f[m]);
}