BZOJ 1597 [Usaco2008 Mar] 土地购买

题意:中文题意,自行理解;

思路:这个题和hdu 1300 的题很像,算是一种类似于二维的扩展,题目不是很难,但窝发现网上的一些题解有些地方说的不是很清楚,在计算斜率优化式的时候,tzw大牛的博客里适宜j为最优解来进行推导的斜率式,所以最后推出来的是维护小于,所以维护下凸包,而一般大家都习惯用k作为最优解,是所以推出来的式上凸包,谈后就是在前面进行的一些小优化,以及快读,(手动写了一下快读,大概懂了小型的快读原理)

代码:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
int n,cnt;
LL x[50005],y[50005],f[50005];
int que[50005];
struct node{LL x,y;}a[50005];
inline bool cmp(node a,node b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}
inline double slop(int a,int b)
{
    return (f[b]-f[a])*1.0/(y[a+1]-y[b+1]);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&a[i].x,&a[i].y);
    }
    cnt=0;
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        while(cnt&&a[i].y>=y[cnt])cnt--;
        x[++cnt]=a[i].x;y[cnt]=a[i].y;
    }
//    for(int i=1;i<=n;i++){
//        printf("test %lld %lld\n",a[i].x,a[i].y);
//    }
    int l=0,r=0;
    for(int i=1;i<=cnt;i++){
        while(l<r&&slop(que[l],que[l+1])<x[i])l++;
        int t=que[l];
        f[i]=f[t]+y[t+1]*x[i];
        while(l<r&&slop(que[r-1],que[r])>slop(que[r],i))r--;
        que[++r]=i;
    }
    printf("%lld\n",f[cnt]);
    return 0;
}

 

posted @ 2018-03-09 11:01  啦啦啦天啦噜  阅读(115)  评论(0编辑  收藏  举报