zoukankan      html  css  js  c++  java
  • bzoj1597[Usaco2008 Mar]土地购买

    bzoj1597[Usaco2008 Mar]土地购买

    题意:

    n块土地,现在要求把土地分成几份,每份费用为该份中土地长最大值和宽最大值成绩,要求最小费用。n≤5000

    题解:

    当一块土地长宽都比另一块土地小时,这块土地可以当作另一块土地的附属品,对答案不影响。因此先按长第一关键字,宽第二关键字排序,然后用单调队列就可以把长宽都被覆盖的土地除去。之后剩在单调队列里的土地长是升序排列,宽是降序排列,故用斜率优化dp:f[i]=max(f[j]+长[i]*宽[j+1]),j比k好当且仅当(f[j]-f[k])/(宽[k+1]-宽[j+1])<长[i]。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 50100
     6 #define ll long long
     7 using namespace std;
     8 
     9 struct str{ll x,y;}; str strs1[maxn],strs2[maxn];
    10 bool cmp(str a,str b){return a.x!=b.x?a.x<b.x:a.y<b.y;}
    11 inline int read(){
    12     char ch=getchar(); int f=1,x=0;
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    14     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    15     return f*x;
    16 }
    17 int n,l,r,m,q[maxn]; ll f[maxn];
    18 double calc(int j,int k){
    19     return (double)(f[j]-f[k])/(double)(strs2[k+1].y-strs2[j+1].y);
    20 }
    21 int main(){
    22     n=read(); inc(i,1,n)strs1[i].x=(ll)read(),strs1[i].y=(ll)read(); sort(strs1+1,strs1+n+1,cmp); m=0;
    23     inc(i,1,n){while(m&&strs2[m].y<=strs1[i].y)m--; strs2[++m]=strs1[i];} l=1; r=1; q[l]=0;
    24     inc(i,1,m){
    25         while(l<r&&calc(q[l],q[l+1])<strs2[i].x)l++; f[i]=f[q[l]]+strs2[i].x*strs2[q[l]+1].y;
    26         while(l<r&&calc(q[r-1],q[r])>calc(q[r],i))r--; q[++r]=i;
    27     }
    28     printf("%lld",f[m]); return 0;
    29 }

    20160612

  • 相关阅读:
    Sql Server2005新特性及性能
    Sql Server Debugger
    .关于 WCF Binding 中 OpenTimeout, CloseTimeout, SendTimeout, ReceiveTimeout 的解释(转载)
    LightSwitch™初体验
    WinDbg / SOS Cheat Sheet
    《Dissecting SQL Server Execution Plans》随记
    轻松掌握用SQL来合并查询
    Oracle:存储过程的使用
    Eclipse和Tomcat的版本问题已解决
    oracle:触发器的使用
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5779802.html
Copyright © 2011-2022 走看看