CF1083E The Fair Nut and Rectangles 题解

CF1083E

题意

一个坐标系中 \(n\) 个矩形,每个矩形左下角在 \((0,0)\),右上角在 \((x_i,y_i)\),有权值 \(a_i\),保证任意两个矩形不出现包含关系,让选出若干个矩形,求矩形面积并减权值和的最大值。

分析

由于保证不出现包含关系,因此将矩形按左右距从小到大排,发现如果一个矩形的上下距不比前面的所有矩形上下距长,而它左右距也一定比前面的所有左右距短,那么前面一定存在一个矩形完全包含它,与题意矛盾。因此矩形的上下距一定单调递增。

\(dp_i\) 表示以 \(i\) 为结尾的矩形序列面积并减权值和的最大值。从 \(dp_j\) 转移多出来的面积并是 \((y_i-y_j)x_i\),因此转移方程为:

\[dp_i=dp_j+(y_i-y_j)x_i-w_i \]

斜率优化即可。

核心代码

struct node{
    int x,y,w;
    bool operator < (const node &o)const{return y<o.y;}
}a[MAXN];
double gety(int i){return dp[i];}double getx(int i){return a[i].y;}
double slope(int i,int j){return (gety(j)-gety(i))/(getx(j)-getx(i));}
signed main(){
    qread(n);int i,j;for(i=1;i<=n;i++) qread(a[i].x,a[i].y,a[i].w);sort(a+1,a+1+n);h=t=1;
    for(i=1;i<=n;i++){
        while(h<t&&slope(q[h],q[h+1])>=a[i].x) h++;
        int j=q[h];dp[i]=dp[j]+(a[i].y-a[j].y)*a[i].x-a[i].w;
        while(h<t&&slope(q[t-1],q[t])<=slope(q[t],i)) t--;q[++t]=i;
        ans=qmax(ans,dp[i]);    
    }printf("%lld\n",ans);
    return 0;
}

record

posted @ 2022-09-13 16:34  l_x_y  阅读(42)  评论(0编辑  收藏  举报