[luogu P3628] [APIO2010]特别行动队
[luogu P3628] [APIO2010]特别行动队
题目描述
你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场。出于默契的考虑,同一支特别行动队中队员的编号 应该连续,即为形如(i, i + 1, ..., i + k)(i,i+1,...,i+k)的序列。 编号为 i 的士兵的初始战斗力为 xi ,一支特别行动队的初始战斗力 x 为队内 士兵初始战斗力之和,即 x = x_i + x_{i+1} + ... + x_{i+k}x=xi+xi+1+...+xi+k。
通过长期的观察,你总结出一支特别行动队的初始战斗力 x 将按如下经验公 式修正为 $x':x' = ax2 + bx + c$,其中 a, b, c 是已知的系数(a < 0)。 作为部队统帅,现在你要为这支部队进行编队,使得所有特别行动队修正后 战斗力之和最大。试求出这个最大和。
例如,你有 4 名士兵, x_1 = 2, x_2 = 2, x_3 = 3, x_4 = 4x1=2,x2=2,x3=3,x4=4。经验公式中的参数为 a = –1, b = 10, c = –20。此时,最佳方案是将士兵组成 3 个特别行动队:第一队包含士兵 1 和士兵 2,第二队包含士兵 3,第三队包含士兵 4。特别行动队的初始战斗力分 别为 4, 3, 4,修正后的战斗力分别为 4, 1, 4。修正后的战斗力和为 9,没有其它 方案能使修正后的战斗力和更大。
输入输出格式
输入格式:
输入由三行组成。第一行包含一个整数 n,表示士兵的总数。第二行包含三 个整数 a, b, c,经验公式中各项的系数。第三行包含 n 个用空格分隔的整数 $x_1, x_2, …, x_n$,分别表示编号为 1, 2, …, n 的士兵的初始战斗力。
输出格式:
输出一个整数,表示所有特别行动队修正后战斗力之和的最大值。
输入输出样例
4 -1 10 -20 2 2 3 4
9
说明
20%的数据中,n ≤ 1000;
50%的数据中,n ≤ 10,000;
100%的数据中,1 ≤ n ≤ 1,000,000,–5 ≤ a ≤ –1,|b| ≤ 10,000,000,|c| ≤ 10,000,000,1 ≤ xi ≤ 100。
斜率DP pro 2。相比上一题,本蒟蒻感觉这题水多了,只是调了一下才A。
设f[i]为前i个人的战斗力最大值,s[i]为前i个人战斗力的和。易得:
f[i]=max{f[j]+a(s[i]-s[j])^2+b(s[i]-s[j])+c}(j<i)
=max{f[j]+as[i]^2-2as[i]s[j]+as[j]^2+bs[i]-bs[j]+c}
设X[i]=as[i]^2,Y[i]=bs[i],则原式
=max{f[j]+X[i]-2as[i]s[j]+X[j]+Y[i]-Y[j]+c}
设P[i]=X[i]+Y[i],Q[i]=X[i]-Y[i],则原式
=max{f[j]+P[i]+Q[i]-2as[i]s[j]+c}
则f[i]=?f[j]+P[i]+Q[i]-2as[i]s[j]+c
则在这个式子里,y=f[j]+Q[j],k=2as[i],x=s[j],b=f[i]-P[i]-c,且y=kx+b。
由于是取max,所以是维护一个上凸包,所以维护一个斜率只降不升的单调队列就可以了。
其中每个点的坐标为(xi,yi)=(s[i],f[i]+Q[i])(可以从最后那个x和y的表达式看出来)。
code:
%:pragma GCC optimize()
#include<bits/stdc++.h>
#define sqr(x) ((x)*(x))
#define LL long long
using namespace std;
;
const double inf=1e18;
int n,l,r; LL A,B,C,ratio,s[N],X[N],Y[N],P[N],Q[N],f[N];
struct point {
LL x,y;
point() {}
point(LL _x,LL _y):x(_x),y(_y) {}
}st[N];
inline int read() {
,f=; char ch=getchar();
:,ch=getchar();
+ch-',ch=getchar();
return x*f;
}
double slope(point u,point v) {
return u.x==v.x?(u.y<v.y?inf:-inf):1.0*(v.y-u.y)/(v.x-u.x);
}
LL get(LL k) {
])>1.0*k) l++;
return st[l].y-k*st[l].x;
}
void insert(point cur) {
],st[r])<slope(st[r-],cur)) r--;
st[++r]=cur;
}
int main() {
n=read(),A=read(),B=read(),C=read(),ratio=A*,s[]=;
; i<=n; i++) s[i]=s[i-]+read();
; i<=n; i++) X[i]=A*sqr(s[i]);
; i<=n; i++) Y[i]=B*s[i];
; i<=n; i++) P[i]=X[i]+Y[i];
; i<=n; i++) Q[i]=X[i]-Y[i];
l=,r=,st[++r]=point(,);
; i<=n; i++) {
f[i]=get(ratio*s[i])+P[i]+C;
insert(point(s[i],f[i]+Q[i]));
}
printf("%lld\n",f[n]);
;
}
[luogu P3628] [APIO2010]特别行动队的更多相关文章
- 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]= ...
- [洛谷P3628] [APIO2010]特别行动队
洛谷题目链接:[APIO2010]特别行动队 题目描述 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 \(n\) 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特别行动 ...
- P3628 [APIO2010]特别行动队
\(\color{#0066ff}{ 题目描述 }\) 你有一支由 \(n\) 名预备役士兵组成的部队,士兵从 \(1\) 到 \(n\) 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑 ...
- 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)
洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...
- 洛谷P3628 [APIO2010]特别行动队(斜率优化)
传送门 先写出转移方程$$dp[i]=max\{dp[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c\}$$ 假设$j$比$k$更优,则有$$dp[j]+a*(s ...
- 洛谷P3628 [APIO2010]特别行动队 斜率优化
裸题,注意队列下标不要写错 Code: #include<cstdio> #include<algorithm> #include<cmath> using nam ...
- 洛谷 P3628 [APIO2010]特别行动队
题意简述 将n个士兵分为若干组,每组连续,编号为i的士兵战斗力为xi 若i~j士兵为一组,该组初始战斗力为\( s = \sum\limits_{k = i}^{j}xk \),实际战斗力\(a * ...
- BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4142 Solved: 1964[Submit][Statu ...
- 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)
dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...
随机推荐
- 用flvplayer.swf在网页中播放视频(网页中flash视频播放的实现)
原:http://blog.csdn.net/ricciozhang/article/details/46868201 由于公司项目的需求,需要在展示一些信息的时候能够播放视频,拿到这个要求,我就从最 ...
- Js 运行机制 (重点!!)
一.引子 本文介绍JavaScript运行机制,这一部分比较抽象,我们先从一道面试题入手: 这一题看似很简单,但如果你不了解JavaScript运行机制,很容易就答错了.题目的答案是依次输出1 2 3 ...
- CSS深入
块元素:div.h1.p等等. 列表的样式: /*使用系统提供的一些样式:例如无序.有序都可以使用circle*/ ul{ list-style-type: circle; } ol{ list-st ...
- phpstorm软件配置端口问题
phpstorm默认的端口号是:63342 但是我装的apache服务器的默认端口是80 网上查找资料,都说可以加listen的端口,比如这里 #Listen 12.34.56.78:80 Lis ...
- 【Java】【反射】
一,java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): Java虚拟机:是运行所有Java程序 ...
- _itemmod_strengthen_item
`enchant_id`升级后的附魔Id `prev_enchant_id` 上级附魔Id `description` 描述,出现在菜单中 `enchantReqId`升级附魔效果的消耗模板 `rem ...
- hdu 3836 Equivalent Sets trajan缩点
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
- ORACLE的rownum用法讲解
如果选择踏足,终有一天你会爱上这条路. 今天讲讲ORACLE中关于ROWNUM的用法: 一.简单介绍一下ROWNUM是什么,可以用来干什么. 答:ROWNUM是一个序列,会根据sql语句自动给你加上一 ...
- 力扣(LeetCode)461. 汉明距离
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意: 0 ≤ x, y < 231. 示例: 输入: x = 1, y ...
- 学习笔记13—python DataFrame获取行数、列数、索引及第几行第几列的值
1. df=DataFrame([{‘A’:’11’,’B’:’12’},{‘A’:’111’,’B’:’121’},{‘A’:’1111’,’B’:’1211’}]) print df.column ...