题目大意

​ 给你一个序列, 将这个序列分成若干段, 每一段的贡献为 \(ax ^ 2 + bx + c\)(x 为 这一段的权值之和)

具体思路


50pts

​ 考虑Dp, 设$Dp_i$为前i个数分成若干段的最大收益, 则$Dp[i] = max(Dp[j-1] + Cost_{i,j})\quad(j ​ 现在想\(cost\) 函数怎么求得

​ 设\(Sum[i]\) 为 i 的前缀和, 则\(cost_{i, j} = a(Sum[i] - Sum[j]) ^ 2 + b (Sum[i] - Sum[j-1]) + c\) 可以\(O(1)\) 求得

100pts

​ 想一想如何优化这个转移, 发现j每次都是从1 至 n , 考虑进行斜率优化

​ 不妨设 x > y 且 x的转移优于y

​ 则\(Dp[x] + a(Sum[i] - Sum[x]) ^ 2 + b (Sum[i] - Sum[x]) + c > Dp[y]+ a(Sum[i] - Sum[y]) ^ 2 + b (Sum[i] - Sum[y]) + c\)

\(\Leftrightarrow Dp[i] + a(Sum[i] ^ 2 + Sum[x] ^ 2 - 2 * Sum[i] * Sum[x]) + b(Sum[i] - Sum[x]) + c > Dp[y] + a(Sum[i] ^ 2 + Sum[y] ^ 2 - 2 * Sum[i] * Sum[x]) + b(Sum[i] - Sum[y]) + c\)

\(\Leftrightarrow Dp[i] + aSum[i] ^ 2 + aSum[x] ^ 2 - 2 * a * Sum[i] * Sum[x] + b Sum[i] - bSum[x ] + c > Dp[y] + a * Sum[y] ^ 2 + a * Sum[y] ^ 2 - 2aSum[i] * Sum[x] + bSum[i] - bSum[y] + c\)

移项、合并同类项得

​ \(Dp[x] - Dp[y] + a(Sum[x ] ^ 2 - Sum[y] ^ 2) - b(Sum[x] - Sum[y]) > 2aSum[i](Sum[x] - Sum[y])\)

\(\Leftrightarrow \frac{Dp[x] - Dp[y] + a(Sun[x] ^ 2 - Sum[y] ^ 2) - b(Sum[x] - Sum[y])}{(Sum[x] - Sum[y])} > 2aSum[i]​\)

\(\Leftrightarrow \frac{Dp[x] + aSum[x] ^ 2 + bSum[x] - Dp[y] - aSum[y]^2 - bSum[y]}{(Sum[x] - Sum[y])} > 2aSum[i]\)

​ 注意:由于题面说\(a < 0 ​\) 所以如果要将a除过去要将符号转向

不难发现左式为一个直线的点斜式,故令其为Slope(x, y) 要满足决策单调性即Slope满足单调性, 用单调队列维护即可

代码实现

#pragma GCC optimize("O2")
#pragma GCC optimize("O3") #include <cstdio> template<class T>
inline void read(T &a){
T s = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') {if(c == '-') w = -1; c = getchar();}
while(c >= '0' && c <= '9') {s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();}
a = s * w;
} #define maxn 1000010
static int n,s[maxn],l,r,q[maxn];
static long long a,b,c,dp[maxn]; #define A(x) (dp[x] + a * s[x] * s[x] - b * s[x])
#define P(x) (s[i] - s[x]) inline double slope(register int x, register int y){
return 1.0 * (A(x) - A(y)) / ((s[x] - s[y]));
} signed main(){
read(n), read(a), read(b), read(c);
for (register int i = 1; i <= n; i++){
int x;
read(x);
s[i] = s[i-1] + x;
} for (register int i = 1; i <= n; i++){
while(l < r && slope(q[l + 1], q[l]) > 2*a*s[i]) l++;
dp[i] = dp[q[l]] + a * P(q[l]) * P(q[l]) + b * P(q[l]) + c;
while(l < r && slope(q[r], q[r-1]) < slope(i, q[r])) r--;
q[++r] = i;
}
printf("%lld", dp[n]);
return 0;
}

题解 P3628 【[APIO2010]特别行动队 】的更多相关文章

  1. 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]= ...

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

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

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

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

  4. P3628 [APIO2010]特别行动队

    \(\color{#0066ff}{ 题目描述 }\) 你有一支由 \(n\) 名预备役士兵组成的部队,士兵从 \(1\) 到 \(n\) 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑 ...

  5. 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)

    洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...

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

    题意简述 将n个士兵分为若干组,每组连续,编号为i的士兵战斗力为xi 若i~j士兵为一组,该组初始战斗力为\( s = \sum\limits_{k = i}^{j}xk \),实际战斗力\(a * ...

  7. 【题解】[APIO2010]特别行动队

    Link 题目大意:一段区间的贡献是\(ax^2+bx+c,x=\sum v\),求一个划分让总区间的价值最大.分段必须连续. \(\text{Solution:}\) 设计\(dp[i]\)表示前\ ...

  8. 洛谷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 ...

  9. 洛谷P3628 [APIO2010]特别行动队 斜率优化

    裸题,注意队列下标不要写错 Code: #include<cstdio> #include<algorithm> #include<cmath> using nam ...

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

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

随机推荐

  1. 打开jsp页面时,显示空白页。

    打开jsp页面时,显示空白页.   #foreach($e in $listPlanItem)          #set($listPlanDetail=$!e.get(2))        < ...

  2. 手机PC文件传输

    QQ啥的现在直接无法全部退出,很纠结后台运行,时不时的来条消息,明明电脑QQ还开着,越来越流氓了. 服务端代码: <%@ Page Language="C#" %> & ...

  3. arduino一些内容

    arduino 套件使用说明书V1.0.pdf, 步进电机 DHT11 传感器另外一脚要接A0 /* Web client This sketch connects to a website (htt ...

  4. Navicat for oracle cannot load OCI DLL

    Navicat for oracle 提示 cannot load OCI DLL87,126,193 instant client package is required for basic and ...

  5. HDU 1503 Advanced Fruits (LCS+DP+递归)

    题意:给定两个字符串,让你求一个最短的字符串,并且这个字符串包含给定的两个. 析:看到这个题,我知道是DP,但是,不会啊...完全没有思路么,我就是个DP渣渣,一直不会做DP. 最后还是参考了一下题解 ...

  6. java thrift返回List异常

    对于下段代码: public List<String> hmget(String key, List<String> fields) throws org.apache.thr ...

  7. NSData与UIImage之间的转换

    1 //NSData转换为UIImage 2 NSData *imageData = [NSData dataWithContentsOfFile: imagePath]; 3 UIImage *im ...

  8. (线段树 区间合并更新)Tunnel Warfare --hdu --1540

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  9. 20155209 2016-2017-2 《Java程序设计》第八周学习总结

    20155209 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从J ...

  10. c++ 内联函数 (讲解的TM真好)

    1.  内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码如下: int max(int a, int b) {  return a > b ? a : b; } 为 ...