zoukankan      html  css  js  c++  java
  • luogu2900:Land Acquisition(斜率优化)

    题意:有N块地,每块地给出的宽和高,然后可以分批买,每次买的代价是所选择的地种最宽*最高。 问怎么买,使得代价和最小。

    思路:显然,先去掉被包括的情况,即如果一个地的宽和高斗比另外一个小,那么久可以删去。 这样,我们得到一些的地宽递增,高递减; 然后得到方程:

    dp[i]=min(dp[j]+w[i]*h[j+1]);斜率优化即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    struct in{
        int w,h;
        bool friend operator <(in p,in q){
            return (p.w^q.w)?p.w<q.w:p.h<q.h;
        }
    }s[maxn],y[maxn];
    ll dp[maxn]; int q[maxn],head,tail;
    int main()
    {
        int N,M,tot=0;
        scanf("%d",&N);
        rep(i,1,N) scanf("%d%d",&s[i].w,&s[i].h);
        sort(s+1,s+N+1);
        for(int i=N;i>=1;i--){
            if(tot&&y[tot].h>s[i].h) continue;
            y[++tot]=s[i];
        }
        rep(i,1,tot) s[i]=y[tot+1-i];
        N=tot; q[++head]=0;  //tail<=head;
        rep(i,1,N) {
            while(tail<head&&1.0*(dp[q[tail+1]]-dp[q[tail]])/(-s[q[tail+1]+1].h+s[q[tail]+1].h)<1LL*s[i].w) tail++;
            dp[i]=dp[q[tail]]+1LL*s[i].w*s[q[tail]+1].h;
            while(tail<head&&1.0*(dp[i]-dp[q[head]])/(-s[i+1].h+s[q[head]+1].h)<=1.0*(dp[i]-dp[q[head-1]])/(-s[i+1].h+s[q[head-1]+1].h)) head--;
            q[++head]=i;
        }
        printf("%lld
    ",dp[N]);
        return 0;
    }
  • 相关阅读:
    (转)Apache与Tomcat 区别联系
    (转)JAVA排序汇总
    (转)Java线程:大总结
    (转)Java线程:新特征-原子量,障碍器
    (转)Java线程:新特征-条件变量
    oracle中的not in和not exists注意事项
    oracle字符乱码的解决方法
    线刷和卡刷的区别
    nexus5刷机
    linux上复制行到另一个文件
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11283702.html
Copyright © 2011-2022 走看看