zoukankan      html  css  js  c++  java
  • 【BZOJ】【1597】【USACO 2008 Mar】土地购买

    DP/斜率优化


      Orz Hzwer……

      想到排序了,但没想到其实可以将序列转化为x递增且y递减的序列……因为x是递增的,若y[i]>y[i-1]那么第i-1个就足够小……以至于可以在搞定第 i 个的同时顺便带走……

      这次仔细写一下斜率优化的过程吧~

      方程:$ f[i]=min{ f[j]+x[i]*y[j+1] } $

      若 $j>k$ 且 决策$j$更优,则有:[ egin{aligned} {f[j]+x[i]*y[j+1]} &<  {f[k]+x[i]*y[k+1]}  \ {f[j]-f[k]} &<  {x[i]*(y[k+1]-y[j+1])} \ {frac{ f[j]-f[k] }{ y[k+1]-y[j+1] }} &<  {x[i]} end{aligned} ]

      至此我们就可以用单调队列来维护决策序列了(一个凸壳)

     1 /**************************************************************
     2     Problem: 1597
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:108 ms
     7     Memory:3036 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1597
    11 #include<cmath>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cstdlib>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 #define pb push_back
    22 using namespace std;
    23 int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    27     return v*=sign;
    28 }
    29 const int N=50010,INF=~0u>>2;
    30 typedef long long LL;
    31 /******************tamplate*********************/
    32  
    33 struct node{
    34     int x,y;
    35     bool operator < (const node&b)const{
    36         return x<b.x || (x==b.x && y<b.y);
    37     }
    38 }a[N];
    39 LL f[N],x[N],y[N];
    40 int q[N];
    41 double slop(int a,int b){
    42     return double(f[b]-f[a])/(y[a+1]-y[b+1]);
    43 }
    44 int main(){
    45     int n=getint(),m=0;
    46     F(i,1,n) a[i].x=getint(),a[i].y=getint();
    47     sort(a+1,a+n+1);
    48     F(i,1,n){
    49        while(m && a[i].y>=y[m]) m--;
    50        x[++m]=a[i].x; y[m]=a[i].y;
    51     }
    52     int l=0,r=0;
    53     F(i,1,m){
    54         while(l<r && slop(q[l],q[l+1])<x[i])l++;
    55         int t=q[l];
    56         f[i]=f[t]+y[t+1]*x[i];
    57         while(l<r && slop(q[r],i)<slop(q[r-1],q[r]))r--;
    58         q[++r]=i;
    59     }
    60     printf("%lld
    ",f[m]);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    软件测试作业1:android手机应用布局之TabActivity
    软件测试作业2:对faulty,error和failure的理解和应用
    python-字符串常用方法、文件简单读写
    python-字典练习题
    python-字典
    python-list 列表 数组
    python基础一循环
    Charles抓包
    Jmeter分布式
    Jmeter如何操作数据库
  • 原文地址:https://www.cnblogs.com/Tunix/p/4332827.html
Copyright © 2011-2022 走看看