zoukankan      html  css  js  c++  java
  • BZOJ 1911: [Apio2010]特别行动队[斜率优化dp]

    1911: [Apio2010]特别行动队

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 4149  Solved: 1970
    [Submit][Status][Discuss]

    Description

    Input

    Output

    Sample Input

    4
    -1 10 -20
    2 2 3 4

    Sample Output

    9

    HINT

    Source

    //斜率优化模板题
    /*
    设f[i]表示从1到i划分为若干组能取得的最大战斗力。
    转移方程:
    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]
    判断队尾的两个元素,以维护上凸的性质
    */ 
    #include<cstdio>
    #include<iostream>
    #define pf(x) ((x)*(x))
    using namespace std;
    typedef long long ll;
    const int N=1e6+5;
    int n,a,b,c,l,r,q[N];
    ll f[N],h[N];
    double slop(int k,int j){
        return (double)(f[j]-f[k]+a*pf(h[j])-a*pf(h[k])-b*h[j]+b*h[k])/(double)(2*a*(h[j]-h[k]));
    }
    int main(){
        scanf("%d%d%d%d",&n,&a,&b,&c);
        for(int i=1,x;i<=n;i++) scanf("%d",&x),h[i]=h[i-1]+x;
        for(int i=1;i<=n;i++){
            for(;l<r&&slop(q[l],q[l+1])<h[i];l++);
            int now=q[l];
            f[i]=f[now]+a*pf(h[i]-h[now])+b*(h[i]-h[now])+c;
            for(;l<r&&slop(q[r],i)<slop(q[r-1],q[r]);r--);
            q[++r]=i;
        }
        cout<<f[n];
        return 0;
    }
  • 相关阅读:
    如何在VS2013中进行Boost单元测试
    C++项目中的extern "C" {}(转)
    C/C++语言中NULL、'’和0的区别
    关于C++“加、减机制”的整理
    C++继承中的public/protected/private
    Systemc在VC++2010安装方法及如何在VC++2010运行Noxim模拟器
    Testbench(转)
    Java高级特性之泛型
    Java高级特性之反射
    Java 输入输出流
  • 原文地址:https://www.cnblogs.com/shenben/p/6290566.html
Copyright © 2011-2022 走看看