传送门

斜率优化dp经典题。

题目中说的很清楚,设f[i]表示前i个数分配出的最大值。

那么有:

f[i]=max(f[j]+A∗(sum[i]−sum[j])2+B∗(sum[i]−sum[j])+C)" role="presentation" style="position: relative;">f[i]=max(f[j]+A∗(sum[i]−sum[j])2+B∗(sum[i]−sum[j])+C)f[i]=max(f[j]+A∗(sum[i]−sum[j])2+B∗(sum[i]−sum[j])+C)

=>

f[i]=max(f[j]+A∗sum[j]2−2∗A∗sum[i]∗sum[j]−B∗sum[j])+A∗sum[i]2+B∗sum[i]+C" role="presentation" style="position: relative;">f[i]=max(f[j]+A∗sum[j]2−2∗A∗sum[i]∗sum[j]−B∗sum[j])+A∗sum[i]2+B∗sum[i]+Cf[i]=max(f[j]+A∗sum[j]2−2∗A∗sum[i]∗sum[j]−B∗sum[j])+A∗sum[i]2+B∗sum[i]+C

同样是比较两个决策k1,k2如果k1优于k2,那么:

f[k1]+A∗sum[k1]2−2∗A∗sum[i]∗sum[k1]−B∗sum[k1]" role="presentation" style="position: relative;">f[k1]+A∗sum[k1]2−2∗A∗sum[i]∗sum[k1]−B∗sum[k1]f[k1]+A∗sum[k1]2−2∗A∗sum[i]∗sum[k1]−B∗sum[k1]

>

f[k2]+A∗sum[k2]2−2∗A∗sum[i]∗sum[k2]−B∗sum[k2])" role="presentation" style="position: relative;">f[k2]+A∗sum[k2]2−2∗A∗sum[i]∗sum[k2]−B∗sum[k2])f[k2]+A∗sum[k2]2−2∗A∗sum[i]∗sum[k2]−B∗sum[k2])

为了让每次查询的斜率单调递增。

我们需要巧妙地移项:

令t[k]=f[k]+A∗sum[k]2−B∗sum[k]" role="presentation" style="position: relative;">t[k]=f[k]+A∗sum[k]2−B∗sum[k]t[k]=f[k]+A∗sum[k]2−B∗sum[k]

=>(t[k1]−t[k2])>2∗A∗sum[i]∗(sum[k1]−sum[k2])" role="presentation" style="position: relative;">(t[k1]−t[k2])>2∗A∗sum[i]∗(sum[k1]−sum[k2])(t[k1]−t[k2])>2∗A∗sum[i]∗(sum[k1]−sum[k2])

=>slope(k1,k2)/A&lt;2∗sum[i]" role="presentation" style="position: relative;">slope(k1,k2)/A<2∗sum[i]slope(k1,k2)/A<2∗sum[i]

搞定了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 1000005
using namespace std;
inline ll read(){
    ll ans=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans*w;
}
int n,q[N],hd,tl;
ll A,B,C,sum[N],f[N];
inline double slope(int i,int j){return 1.0*(sum[i]+sum[j])+(1.0*(f[i]-f[j])/(sum[i]-sum[j])-B)*1.0/A;}
int main(){
    n=read(),A=read(),B=read(),C=read(),hd=tl=1;
    for(int i=1;i<=n;++i)sum[i]=sum[i-1]+read();
    for(int i=1;i<=n;++i){
        while(hd<tl&&slope(q[hd+1],q[hd])<2*sum[i])++hd;
        int j=q[hd];
        f[i]=f[j]+A*(sum[i]-sum[j])*(sum[i]-sum[j])+B*(sum[i]-sum[j])+C;
        while(hd<tl&&slope(i,q[tl])<slope(q[tl],q[tl-1]))--tl;
        q[++tl]=i;
    }
    cout<<f[n];
    return 0;
}

2018.09.07 bzoj1911: [Apio2010]特别行动队(斜率优化dp)的更多相关文章

  1. bzoj1911[Apio2010]特别行动队 斜率优化dp

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 5057  Solved: 2492[Submit][Statu ...

  2. bzoj1911 [Apio2010]特别行动队——斜率优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1911 相当明显的斜率优化,很好做: 注意slp里面要有(double),以免出现精度问题. ...

  3. BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 4142  Solved: 1964[Submit][Statu ...

  4. [APIO2010]特别行动队 --- 斜率优化DP

    [APIO2010]特别行动队 题面很直白,就不放了. 太套路了,做起来没点感觉了. \(dp(i)=dp(j)+a*(s(i)-s(j))^{2}+b*(s(i)-s(j))+c\) 直接推出一个斜 ...

  5. APIO2010 特别行动队 & 斜率优化DP算法笔记

    做完此题之后 自己应该算是真正理解了斜率优化DP 根据状态转移方程$f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j]$ 可以变形为 $f[i]=max((a*sum[j ...

  6. 【BZOJ1911】[Apio2010]特别行动队 斜率优化DP

    想了好久啊....——黑字为第一次更新.——这里是第二次更新,维护上下凸包据题而论,第一种方法是化式子的方法,需要好的化式子的方法,第二种是偏向几何,十分好想,纯正的维护凸包的方法,推荐. 用了我感觉 ...

  7. [Bzoj1911][Apio2010]特别行动队(斜率优化)

    题目链接 斜率优化的经典模型,将序列分成若干段,每段有一个权值计算方法,求权值和最大/小 暴力的dp $O(n^{2})$ dp[i]为1-i的序列的最优解.sum[i]为前缀和,$D(i)=ax^{ ...

  8. 2018.09.07 bzoj1096: [ZJOI2007]仓库建设(斜率优化dp)

    传送门 斜率优化dp经典题. 令f[i]表示i这个地方修建仓库的最优值,那么答案就是f[n]. 用dis[i]表示i到1的距离,sump[i]表示1~i所有工厂的p之和,sum[i]表示1~i所有工厂 ...

  9. bzoj 1911: [Apio2010]特别行动队 -- 斜率优化

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Description Input Output Sample Input 4 ...

随机推荐

  1. 一个NPOI导出到excel文件的范例记录

    '使用NPOI写入新创建的excel文件,导出文件: Private Sub Sub_WriteXls() Dim XlsBook As XSSFWorkbook Dim XlsSheet As XS ...

  2. Vue2.0中v-for迭代语法变化(key、index)

    语法发生了变化:http://blog.csdn.net/sinat_35512245/article/details/53966788 新数组语法 value in arr (value, inde ...

  3. 表格(table)

    Title 主机名 端口 操作 1111 10023 查看详情 修改 表头1 表头1 表头1 表头1 1 1 1 1 1 1 1 1 1 <!DOCTYPE html><html l ...

  4. Mysql 表名大写 找不到表

    原来Linux下的MySQL默认是区分表名大小写的,通过如下设置,可以让MySQL不区分表名大小写:1.用root登录,修改 /etc/my.cnf:2.在[mysqld]节点下,加入一行: lowe ...

  5. python之函数嵌套与闭包

    一:函数的嵌套:在函数内部在定义一个函数,一层套一层 def father(name): print("from father %s" %name) def son(): prin ...

  6. focusin 事件| focusout事件

    focusin 定义和用法 当元素(或在其内的任意元素)获得焦点时发生 focusin 事件. 当在元素或在其内的任意元素上发生 focus 事件时,focusin() 方法添加要运行的函数. 与 f ...

  7. ubuntu 安装qq方案

    from: http://blog.csdn.net/fuchaosz/article/details/51919607 安装wineQQ国际版 VirtualBox安装windows,再安装QQ,然 ...

  8. (1)shiro简介和第一个demo

    之前一直在用shiro开发,不过只是会使用,并没有深入了解,最近有时间学习了一下,把最近学习所得分享一下. shiro简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授 ...

  9. STS或eclipse安装SVN插件

    安装sts--SVN插件 简介:sts是与eclipse类似的Java IDE开发工具(不了解的百度) 1.sts菜单栏 help->install New Software 依据大家的版本选择 ...

  10. python 写hive循环脚本

    要一个月的数据 一次跑一周的数据 ,建表用插入数据的方法: import os, sys reload(sys); sys.setdefaultencoding( "utf-8" ...