zoukankan      html  css  js  c++  java
  • BZOJ4850/BZOJ2216 JSOI2016灯塔/Poi2011Lightning Conductor(决策单调性)

      即对每个i最大化hj-hi+sqrt(|i-j|)。先把绝对值去掉,正反各做一次即可。注意到当x>y时,sqrt(x+1)-sqrt(x)<sqrt(y+1)-sqrt(y),所以若对于i选择j比选择k更优(j>k),对于i+1~n也会是这样,即满足决策单调性(虽然并不能算作dp)。

      可以这样使用决策单调性优化:维护一个栈,存储当前考虑的这些位置中每个位置向哪个区间转移最优。转移时在栈中二分,然后考虑更新栈,如果新加入的位置向栈顶的整个区间转移都是最优的,直接将栈顶位置弹出,否则二分找一个区间的分割点,最后把这个新位置加入栈中即可。

      寻找决策区间时小心不要把已更新过的位置算进去。注意维护决策时不能对答案取整,否则会影响决策区间。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,a[N],q[N],l[N],r[N],id[N],top;
    double ans[N];
    double calc(int i,int j){return a[j]-a[i]+sqrt(i-j);}
    void work()
    {
        l[1]=1,r[1]=n,id[1]=1,top=1;
        for (int i=2;i<=n;i++)
        {
            int left=1,right=top,x;
            while (left<=right)
            {
                int mid=left+right>>1;
                if (l[mid]<=i&&r[mid]>=i) {x=mid;break;}
                else if (r[mid]<i) left=mid+1;
                else right=mid-1;
            }
            ans[i]=max(ans[i],calc(i,id[x]));
            while (top&&l[top]>=i&&calc(l[top],id[top])<calc(l[top],i)) top--;
            left=max(l[top],i),right=r[top],x=r[top]+1;
            while (left<=right)
            {
                int mid=left+right>>1;
                if (calc(mid,id[top])<calc(mid,i)) x=mid,right=mid-1;
                else left=mid+1;
            }
            r[top]=x-1;
            if (x<=n) top++,l[top]=x,r[top]=n,id[top]=i;
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4850.in","r",stdin);
        freopen("bzoj4850.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++) a[i]=read();
        work();reverse(a+1,a+n+1),reverse(ans+1,ans+n+1);
        work();for (int i=n;i;i--) printf("%.0f
    ",ceil(ans[i]));
        return 0;
    }
  • 相关阅读:
    php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项
    Linux 文件系统IO性能优化【转】
    MOOC Linux内核之旅小结【转】
    python实战===教你用微信每天给女朋友说晚安【转】
    wxpy: 用 Python 玩微信【转】
    AMBA总线协议AHB、APB、AXI对比分析【转】
    高手进阶,终极内存技术指南——完整/进阶版 II (转)【转】
    ARMCC和GCC编译ARM代码的软浮点和硬浮点问题 【转】
    程序员必知之浮点数运算原理详解【转】
    Hash算法【转】
  • 原文地址:https://www.cnblogs.com/Gloid/p/10003442.html
Copyright © 2011-2022 走看看