zoukankan      html  css  js  c++  java
  • APIO2010 特别行动队 & 斜率优化DP算法笔记

    做完此题之后 自己应该算是真正理解了斜率优化DP

    根据状态转移方程$f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]$

    可以变形为 $f[i]=max((a*sum[j]^2-b*sum[j])-(2a*sum[j]*sum[i]))+(a*sum[i]^2+b*sum[i]+c)$

    我们可以把每个决策映射到平面上的一个点

    其中坐标$x=(a*sum[j]^2-b*sum[j])$代表此决策的固定价值(与转移到哪无关)

    坐标$y=(-2a*sum[j])$代表此决策的潜在价值(与转移到哪有关) 

    这样我们就可以开始用单调队列维护一个$x$递增 $y$递减的凸壳

    ------------------------------------------------------------------------

    对于每次加入进来的一个新元素

    我们先对队首的两个决策进行判断 若某决策现有价值不如后面的决策则将其删去

    (因为维护的单调队列中的决策潜在价值是递增的)

    然后更新新加的元素的最大值

    再对新加元素与队尾的两个决策间进行判断

    如果队尾第一个的决策在新加决策和前面所有决策所构成凸壳之内

    那么这个决策永远不可能同时优于前一个决策和新加决策 所以就直接删掉就好了

    最后将新加的决策加入单调队列

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define rep(i,n) for(int i=1;i<=n;++i)
    #define imax(x,y) (x>y?x:y)
    #define imin(x,y) (x<y?x:y)
    using namespace std;
    const int N=1000010;
    int sum[N],q[N];
    long long f[N];
    int n;
    long long a,b,c;
    long long solve(int x,int y)
    {
        return f[x]+a*(sum[y]-sum[x])*(sum[y]-sum[x])+b*(sum[y]-sum[x])+c;
    }
    long long solvex(int x)
    {
        return f[x]+a*sum[x]*sum[x]-b*sum[x];
    }
    bool judge(int x,int y,int z)
    {
        long long tx=solvex(x),ty=solvex(y),tz=solvex(z);
        return (ty-tx)*(sum[z]-sum[x])<=(tz-tx)*(sum[y]-sum[x]);//约掉了-2a
    }
    int main()
    {
        scanf("%d",&n);
        scanf("%lld%lld%lld",&a,&b,&c);
        rep(i,n)
        {
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
        }
        int ifront=1,itail=1;
        q[1]=0;
        rep(i,n)
        {
            while(ifront<itail&&solve(q[ifront],i)<=solve(q[ifront+1],i))
                ++ifront;
            f[i]=solve(q[ifront],i);
            while(ifront<itail&&judge(q[itail-1],q[itail],i))
                --itail;
            q[++itail]=i;
        }
        printf("%lld",f[n]);
        return 0;
    }
  • 相关阅读:
    编写测试类实现并发访问固定URL(亲测能用!!!)
    java项目添加log4j打印日志+转换系统时间
    springboot项目没错,但就是报红叉
    我想查看数据库名,输入命令:select name from v$database;为什么会说表和视图不存在
    DRUID连接池的实用 配置详解+使用方法+监控方式(太强大了!!!)
    Druid连接池 属性说明
    springBoot2.2.0+mybatis-xml文件方式+Oracle11g+jsp页面,实现简单的CRUD
    s5-12 RIP
    s5-12 RIP
    s5-13 RIP 为什么会 衰败
  • 原文地址:https://www.cnblogs.com/sagitta/p/4626683.html
Copyright © 2011-2022 走看看