居然还有奶牛题没被权限(感动QAQ)
如果有包含关系的话就可以去掉小的,所以可以先排完序后去掉逆序的
然后长和宽都是单调的,就可以出方程f[i]=max{f[j]+a[j]b[i]}
易得(f[j-1]-f[k-1])/(a[j]-a[k])<b[i](易项时注意符号问题)
单调队列维护凸包即可
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 50000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 struct tmp{ 18 int x,y; 19 }c[NM]; 20 int n,q[NM],qh,qt,_t,a[NM],b[NM],m; 21 ll f[NM]; 22 bool cmp(tmp x,tmp y){ 23 return x.x>y.x||(x.x==y.x&&x.y>y.y); 24 } 25 double slope(int x,int y){ 26 return (double)(f[y-1]-f[x-1])/(a[x]-a[y]); 27 } 28 int main(){ 29 freopen("data.in","r",stdin); 30 n=read(); 31 inc(i,1,n){ 32 c[i].x=read();c[i].y=read(); 33 } 34 sort(c+1,c+n+1,cmp); 35 inc(i,1,n) 36 if(_t<c[i].y){ 37 a[++m]=c[i].x;b[m]=c[i].y;_t=c[i].y; 38 } 39 // inc(i,1,n)printf("%d %d ",a[i],b[i]); 40 qh=qt=1;q[1]=1;f[1]=(ll)a[1]*b[1];n=m; 41 inc(i,2,n){ 42 while(qh+1<=qt&&slope(q[qh],q[qh+1])<b[i])qh++; 43 int j=q[qh]; 44 f[i]=min(f[j-1]+(ll)a[j]*b[i],f[i-1]+(ll)a[i]*b[i]); 45 while(qh+1<=qt&&slope(q[qt-1],q[qt])>=slope(q[qt],i))qt--; 46 q[++qt]=i; 47 } 48 // inc(i,1,n)printf("%d ",f[i]);printf(" "); 49 printf("%lld ",f[n]); 50 return 0; 51 }