BZOJ 1597 [Usaco2008 Mar]土地购买

来源:互联网 发布:嘀哩嘀哩软件下载 编辑:程序博客网 时间:2024/05/16 01:38

斜率优化

考虑到如果一个长方形可以被另一个长方形覆盖,那么它就可以直接忽略。

然后按x递增y递减的顺序排序,如果取了i和j,那么i和j之间的长方形显然是可以都取的而不会产生新的贡献。于是可以DP,然后发现可以斜率优化

还有一个小细节就是斜率优化的时候要加入f[0]的情况,因为可以不取前面的

#include<cstdio>#include<algorithm>#define N 50005#define ll long longusing namespace std;struct rect{    int x, y;}rec[N];const int TEMP = N-1;ll f[N], x[N], y[N];bool cmp(rect a, rect b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}double calc(int i, int j, int k){    return 1.0*(x[j]-x[i])*(y[k]-y[i])-(y[j]-y[i])*(x[k]-x[i]);}int main(){    int n;     scanf("%d",&n);    for(int i = 1; i <= n; i++)          scanf("%d%d",&rec[i].x,&rec[i].y);    sort(rec+1,rec+1+n,cmp);    int pos=0;    for(int i = 1; i <= n; i++)    {        while(pos && rec[i].y>=rec[pos].y)pos--;        rec[++pos]=rec[i];    }    n=pos;    int head=0, tail=1;//     x[head]=rec[1].y;//注意这两行,保留一个f[i]从f[0]转移的方案     for(int i = 1; i <= n; i++)    {        while(tail-head>1 && y[head+1]-y[head]>=(x[head+1]-x[head])*rec[i].x)head++;        f[i]=x[head]*rec[i].x-y[head];        x[TEMP]=rec[i+1].y;        y[TEMP]=-f[i];        while(tail-head>1 && calc(tail-2,tail-1,TEMP)<=0)tail--;        x[tail]=x[TEMP];        y[tail]=y[TEMP];        tail++;    }    printf("%lld\n",f[n]);}
0 0