zoukankan      html  css  js  c++  java
  • P3515 [POI2011]Lightning Conductor[决策单调性优化]

    给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$forall j eq i $有$ p_i>=a_j-a_i+ sqrt{|i-j|}$。


    绝对值很烦 ,先分左右情况单独做。现在假设j都在i左边,则$ p_{i} = max { a_{j}-a_{i}+ sqrt{i-j} } = max { a_{j}+ sqrt{i-j} } - a_i$。带根号,不易斜率优化,考虑证决策单调性。

    假设最优决策为j,j之前的任意决策称之为$j'$,只与$j$有关的项令之为$h[j]=a[j]$,则有

    $h[j]+sqrt{i-j} geqslant h[j']+sqrt{i-j'}$  ①

    现要证$ h[j]+sqrt{i-j+1} geqslant h[j']+sqrt{i-j'+1}$ ②

    即证$ sqrt{i-j+1}-sqrt{i-j} geqslant sqrt{i-j'+1}-sqrt{i-j'}$($②-①$得)

    那么把它看成关于$j$的函数看单调性,设$g(j)=sqrt{i-j+1}+sqrt{i-j}$

    对其求导。

    $g'(j)=[(i-j+1)^{frac{1}{2}}]' - [(i-j)^{frac{1}{2}}]'=-frac{1}{2} (i-j+1)^{-frac{1}{2}} + frac{1}{2} (i-j)^{-frac{1}{2}}=frac{1}{2} (frac{1}{sqrt{i-j}}-frac{1}{sqrt{i-j+1}})$

    由$ i-j<i-j+1$知$frac{1}{2} (frac{1}{sqrt{i-j}}-frac{1}{sqrt{i-j+1}}) > 0$则函数$g(j)$单调增,则上不等式成立,满足单调性。

    证完决策单调性优化即可。


    错误记录:第二次写的时候line37写成l<r了,,丢人。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef double db;
     5 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
     6 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
     7 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
     8 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
     9 template<typename T>inline T read(T&x){
    10     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    11     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    12 }
    13 const int N=500000+7;
    14 struct kochiya_sanae{
    15     int l,r,pos;
    16     kochiya_sanae(int l0=0,int r0=0,int pos0=0):l(l0),r(r0),pos(pos0){}
    17 }q[N];
    18 db sq[N],f[N],h[N];
    19 int n,l,r;
    20 inline void preprocess(){for(register int i=1;i<=n;++i)sq[i]=sqrt((db)i);}
    21 inline db calc(int j,int i){return (db)h[j]+sq[i-j];}
    22 inline int find_pos(int L,int R,int j,int i){
    23     ++R;int mid;
    24     while(L<R){
    25         mid=L+R>>1;
    26         if(calc(j,mid)<=calc(i,mid))R=mid;
    27         else L=mid+1;
    28     }
    29     return R;
    30 }
    31 inline void dp(){
    32     q[l=r=1]=kochiya_sanae(0,n,0);
    33     for(register int i=1;i<=n;++i){
    34         if(q[l].r<i)++l;else ++q[l].l;
    35         MAX(f[i],calc(q[l].pos,i)-h[i]);
    36         while(l<=r&&calc(q[r].pos,q[r].l)<=calc(i,q[r].l))--r;
    37         if(r<l)q[r=l]=kochiya_sanae(i,n,i);
    38         else{
    39             int k;
    40             if(calc(q[r].pos,q[r].r)>calc(i,q[r].r))k=q[r].r+1;
    41             else k=find_pos(q[r].l,q[r].r,q[r].pos,i);
    42             if(k<=n)q[r].r=k-1,q[++r]=kochiya_sanae(k,n,i);
    43         }
    44     }
    45 }
    46 
    47 int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
    48     read(n);for(register int i=1;i<=n;++i)read(h[i]);h[0]=-3;
    49     preprocess();dp();reverse(h+1,h+n+1);reverse(f+1,f+n+1);dp();
    50     for(register int i=n;i;--i)printf("%d
    ",(int)ceil(f[i]));
    51     return 0;
    52 }
  • 相关阅读:
    终于想起了博客园密码
    关于GCD的8题
    idea快捷键 ctrl + shift + f 失效解决方法
    前端和后端日期类型交互
    poi、easypoi和easyexcel的使用
    事务总结
    数据库cte的理解和使用
    mybatis 调用存储过程没有返回值
    postgresql 查询锁表并解锁
    tigase网络核心SockThread详解(十九)
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10468742.html
Copyright © 2011-2022 走看看