• 【BZOJ 1911】 [Apio2010]特别行动队


    Description

    Input

    Output

    Sample Input

    4
    -1 10 -20
    2 2 3 4

    Sample Output

    9

    HINT

     
    转移方程
    f[i]=max(f[j]+a*(h[i]-h[j])^2+b*(h[i]-h[j])+c)
    //h数组为前缀和
    如此显然的方程复杂度是O(n^2) 的

    设j>k且j比k右,则有
    f[j]+a*(h[i]-h[j])^2+b*(h[i]-h[j])+c>f[k]+a*(h[i]-h[k])^2+b*(h[i]-h[k])+c
    移项可得
    f[j]-f[k]+a*h[j]^2-a*h[k]^2-b*h[j]+b*h[k]>2*a*(h[j]-h[k])*h[i]
    由此方程我们可以建立一个队列
    当队首元素与第二个元素k,j不满足上式时,队首++
    取出第一个元素O(1)的更新f[j]
    判断队尾的两个元素,以维护上凸的性质

     1 #include<cstdio>
     2 #define ll long long
     3 const int N=1000005;
     4 int a,b,c,n,l,r;
     5 int x[N],q[N];
     6 ll f[N],h[N];
     7 ll sqr(ll x) {return x*x;}
     8 double slop(int k,int j)
     9 {return (double)(f[j]-f[k]+a*sqr(h[j])-a*sqr(h[k])-b*h[j]+b*h[k])/(double)(2*a*(h[j]-h[k]));}
    10  
    11 int main(){
    12     scanf("%d",&n);
    13     scanf("%d%d%d",&a,&b,&c);
    14     for (int i=1;i<=n;i++) {
    15         scanf("%d",&x[i]);
    16         h[i]=h[i-1]+x[i];
    17     }
    18     for (int i=1;i<=n;i++){
    19         while(l<r&&slop(q[l],q[l+1])<h[i])l++;
    20         int now=q[l];
    21         f[i]=f[now]+a*sqr((h[i]-h[now]))+b*(h[i]-h[now])+c;
    22         while(l<r&&slop(q[r],i)<slop(q[r-1],q[r])) r--;
    23         q[++r]=i;
    24     }
    25     printf("%lld",f[n]);
    26 } 
  • 相关阅读:
    视图,触发器,事物,储存过程,函数,流程控制
    mysql之其他
    web前端之html
    mysql之索引
    Android minHeight/Width,maxHeight/Width
    Android GridView(九宫图)
    Android padding和margin的区别
    android:scaleType属性
    android:visibility
    Android RelativeLayout常用属性介绍
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5191633.html
Copyright © 2020-2023  润新知