题目

洛谷 & bzoj

简要题意:给定一个长为\(n\)的序列\(\{s_i\}\)与常数\(a,b,c\),序列的一个连续子段\(s_i\)到\(s_j\)的贡献为\(at^2+bt+c\),\(t\)为子段内元素和,求一种切割序列的方法,使得总贡献最大,输出最大值

Solution

前置技能:Dp、斜率优化

这题看上去和\(APIO2010\)序列分割比较像,只是那道题更简单,要能做出这题首先在看到时就至少要想到\(O(n^2)\)的Dp,如果这个不会的话建议不要做这题,Dp方程:

\(f[i]=max\{f[j]+v(\sum_{k=i}^js[k])\},v(x)\)为计算贡献的函数

考虑到题目给的数据明显是\(O(n)\)的算法,也就是斜率优化的队列可以解决,首先设序列前缀和为\(s\)(之后不会提及原序列,用\(s\)表示序列前缀和)

\(f[i]=max\{f[j]+v(s[j]-s[i])\},j\in [1,i)\)

考虑从\(k\)转移比\(j\)优,则有

\(f_j+a(s_i-s_j)^2+b(s_i-s_j)+c\leq f_k+a(s_i-s_k)^2+b(s_i-s_k)+c\)

消去同类项

\(f_j+as_j^2-2as_is_j-bs_j\leq f_k+as_k^2-2as_is_k-bs_k\)

将\(a,b\)分别汇总

\(f_j+b(s_k-s_j)\leq f_k+a(2s_is_j-2s_is_k+s_k^2-s_j^2)\)

提出右边的公因式

\(f_j+b(s_k-s_j)\leq f_k+a(s_j-s_k)(2s_i-s_j-s_k)\)

左右拥有公因式合并

\(f_j-f_k\leq (s_j-s_k)\bigl[a(2s_i-s_j-s_k)+b\bigr]\)

转移(分式居中看得清楚一些)

\[\frac {f_j-f_k}{s_j-s_k}\leq a(2s_i-s_j-s_k)+b
\]

剔除含\(i\)的部分(这里别忘记\(a<0\),不等式要反向)

\[2s_i\geq \frac {\frac {f_j-f_k}{s_j-s_k}-b}a+s_j+s_k
\]

单调队列维护即可

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register template <typename _Tp> inline _Tp read(_Tp&x){
char c11=getchar(),ob=0;x=0;
while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')ob=1,c11=getchar();
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
} const int N=1001000;
int q[N],he,ta,n;
ll f[N],s[N],a,b,c; inline double slp(int i,int j)
{return (((1.0*f[j]-f[i])/(1.0*s[j]-s[i]))-b)/a+(1.0*s[i]+s[j]);} int main(){
read(n);read(a);read(b);read(c);he=ta=1;
for(rg int i=1;i<=n;++i)read(s[i]),s[i]+=s[i-1];
for(rg int i=1,j;i<=n;++i){
while(he<ta&&slp(q[he],q[he+1])<=s[i]+s[i])++he;j=q[he];
f[i]=f[j]+a*(s[i]-s[j])*(s[i]-s[j])+b*(s[i]-s[j])+c;
while(he<ta&&slp(q[ta],i)<=slp(q[ta-1],q[ta]))--ta;
q[++ta]=i;
}printf("%lld\n",f[n]);
return 0;
}

题解-APIO2010 特别行动队的更多相关文章

  1. 【bzoj1911】[Apio2010]特别行动队

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

  2. [洛谷P3628] [APIO2010]特别行动队

    洛谷题目链接:[APIO2010]特别行动队 题目描述 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 \(n\) 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特别行动 ...

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

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

  4. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  5. bzoj 1911 [Apio2010]特别行动队(斜率优化+DP)

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

  6. BZOJ 1911: [Apio2010]特别行动队( dp + 斜率优化 )

    sum为战斗力的前缀和 dp(x) = max( dp(p)+A*(sumx-sump)2+B*(sumx-sump)+C )(0≤p<x) 然后斜率优化...懒得写下去了... ------- ...

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

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

  8. P3628 [APIO2010]特别行动队(斜率优化dp)

    P3628 [APIO2010]特别行动队 设$s[i]$为战斗力前缀和 显然我们可以列出方程 $f[i]=f[j]+a*(s[i]-s[j])^{2}+b*(s[i]-s[j])+c$ $f[i]= ...

  9. [luogu P3628] [APIO2010]特别行动队

    [luogu P3628] [APIO2010]特别行动队 题目描述 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特 ...

随机推荐

  1. Sublime Text 3 Mac常用快捷键与注意事项

    大多数情况下容易忘记的快捷键,在此整理了一下. 编辑快捷键:cmd+L:选择行(重复按下将下一行加入选择):cmd+D:选择词(重复按下时多重选择相同的词进行多重编辑):cmd+shift+D 复制光 ...

  2. Dubbo服务端结合maven打jar包

    <build>        <finalName>odao-weixin-user</finalName>        <resources>   ...

  3. js实现table用鼠标改变td的宽度,固定table宽度和高度超过显示点

    <!DOCTYPE HTML> <html> <head> <meta charset="gbk"> <title>ta ...

  4. HTML第五耍 表格标签

    HTML标记语言中可以使用table标签创建表格. 表格由 <table> 标签来定义.每个表格均有若干行(由 <tr> 标签定义),字母 tr 指表格数据(table row ...

  5. svn各种表示含义及解决

  6. Java入门系列 泛型

    前言 <Java编程思想>第四版足足用了75页来讲泛型——厚厚的一沓内容,很容易让人头大——但其实根本不用这么多,只需要一句话:我是一个泛型队列,狗可以站进来,猫也可以站进来,但最好不要既 ...

  7. 四十、Linux 线程——互斥锁和读写锁

    40.1 互斥锁 40.1.1 介绍 互斥锁(mutex)是一种简单的加锁的方法来控制对共享资源的访问. 在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行访问. 若其他线程 ...

  8. GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】

    4.1.2 符号解析与重定位 (1)重定位 在完成空间和地址的分配步骤之后,链接器就进入了符号解析和重定位的步骤,这是静态链接的核心部分. 先看看 a.o 的反汇编文件: objdump -d a.o ...

  9. 代码管理工具:使用github和git工具管理自己的代码

    一.git工具和账户创建 1.1 安装 Git 是 Linus Torvalds 最近实现的源代码管理软件."Git 是一个快速.可扩展的分布式版本控制系统,它具有极为丰富的命令集,对内部系 ...

  10. mysql单表删除记录DELETE

    DELETE FROM tbl_name  [WHERE where_condition] mysql> SELECT * FROM users;+----+----------+------- ...