【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)
题目链接
假设有\(3\)段\(a,b,c\)
先切\(ab\)和先切\(bc\)的价值分别为
\(a(b+c)+bc=ab+bc+ac\)
\((a+b)c+ab=ab+bc+ac\)
归纳一下可以发现切的顺序并不影响总价值。
于是设\(f[i][j]\)表示前\(i\)个数切\(j\)次的最大价值,转移方程就很简单了。
然后斜率优化一下就能降时间复杂度降到\(O(nk)\)
\(f[i][j]=f[k][j-1]+sum[k]*(sum[i]-sum[k])\)
\(f[k][j-1]-sum[k]^2=-sum[i]*sum[k]+f[i][j]\)
水分神器斜率优化
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100010;
const int MAXM = 205;
#define ll long long
#define re register
int n, m, p;
int q[MAXN], head, tail, sum[MAXN], fa[MAXN][MAXM];
ll f[MAXN][MAXM];
inline double k(int t, int i, int j){
if(sum[i] == sum[j]) return -2e18;
return (double)(f[i][t] - f[j][t] - (ll)sum[i] * sum[i] + (ll)sum[j] * sum[j]) / (sum[i] - sum[j]);
}
int main(){
scanf("%d%d", &n, &m);
for(re int i = 1; i <= n; ++i){
scanf("%d", &p);
sum[i] = sum[i - 1] + p;
}
for(re int j = 1; j <= m; ++j){
head = tail = 0;
for(re int i = 1; i <= n; ++i){
while(head < tail && k(j - 1, q[head], q[head + 1]) > -sum[i]) ++head;
re int l = q[head];
f[i][j] = f[l][j - 1] + (ll)sum[l] * (sum[i] - sum[l]);
fa[i][j] = l;
while(head < tail && k(j - 1, q[tail - 1], q[tail]) <= k(j - 1, q[tail], i)) --tail;
q[++tail] = i;
}
}
printf("%lld\n", f[n][m]);
int now = fa[n][m];
while(m--){
printf("%d ", now);
now = fa[now][m];
}
return 0;
}
【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)的更多相关文章
- 洛谷 P3648 [APIO2014]序列分割 解题报告
P3648 [APIO2014]序列分割 题目描述 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的 ...
- 洛谷P3648 [APIO2014]序列分割(斜率优化)
传送门 没想到这种多个状态转移的还能用上斜率优化……学到了…… 首先我们可以发现,切的顺序对最终答案是没有影响的 比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得 ...
- 洛谷 P3648 [APIO2014]序列分割
题意简述 有一个长度为n的序列,分成k + 1非空的块, 选择两个相邻元素把这个块从中间分开,得到两个非空的块. 每次操作后你将获得那两个新产生的块的元素和的乘积的分数.求总得分最大值. 题解思路 f ...
- P3648 [APIO2014]序列分割 斜率优化
题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...
- bzoj3675[Apio2014]序列分割 斜率优化dp
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3508 Solved: 1402[Submit][Stat ...
- [APIO2014]序列分割 --- 斜率优化DP
[APIO2014]序列分割 题目大意: 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的操作\(k ...
- 洛谷3648 [APIO2014]序列分割(斜率优化+dp)
首先对于这个题目. qwq 存在一个性质就是,最终的答案只跟你的分割的位置有关,而和顺序无关. 举一个小栗子 \(a\ b\ c\) 将这个东西分成两块. 如果我们先分割\(ab\)之间的话,\(an ...
- BZOJ3675: [Apio2014]序列分割(斜率优化)
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4186 Solved: 1629[Submit][Status][Discuss] Descript ...
- 【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
随机推荐
- jQuery之过滤元素
还是那句话,这些知识一个小小的练习,更多的请看jQuery手册 在jQuery对象中的元素对象数组中过滤出一部分元素来1. first()2. last()3. eq(index|-index)4. ...
- 软工网络15团队作业4-DAY7
每日例会 昨天的工作. 张陈东芳:sql连接的基本完成,尝试被其他类调用,未导入全部商品信息: 吴敏烽:基本完成商品信息的调用: 周汉麟:设定商品的调用规则: 林振斌:设计缓存区代码,用于存取最近浏览 ...
- maven将依赖打入jar包
将 依赖打入jar包,由于maven管理了所有的依赖,所以将项目的代码和依赖打成一个包对它来说是顺理成章的功能.maven的这个功能之前就用过,但这 次使用时忘了细节,只记得用maven的assemb ...
- 【Linux 命令】- more和less
more命令 more功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b ...
- C 语言疑难杂症 [转:http://blog.chinaunix.net/uid-20688544-id-1894880.html]
无聊在网上找了些C语言的东东练一下手,竟然发现其实还有好多细节之前,没注意到,该好好复习一下先. 解决掉的问题先不发出来,把疑问的先做个笔记,过几天解决了就回来修改补上. #include < ...
- PHP之array_flip()方法
array_flip — 交换数组中的键和值 array array_flip ( array $trans ) array_flip() 返回一个反转后的 array,例如 trans 中的键名变成 ...
- Privoxy
Privoxy 前沿: 这个玩意我以前都没听说过,今天在别人的帮助下试了试,只想说:谁还能阻挡我,我就是要USA....ps:在此感谢每一个帮助我的人 介绍: Privoxy是一款带过滤功能的代理服务 ...
- 洛谷P3933 Chtholly Nota Seniorious 【二分 + 贪心 + 矩阵旋转】
威廉需要调整圣剑的状态,因此他将瑟尼欧尼斯拆分护符,组成了一个nnn行mmm列的矩阵. 每一个护符都有自己的魔力值.现在为了测试圣剑,你需要将这些护符分成 A,B两部分. 要求如下: 圣剑的所有护符, ...
- 【loj6436】【pkusc2018】神仙的游戏
Portal --> pkuscD2T2(loj6436) Solution 个人觉得是道很好的法法塔题qwq 一开始的时候想偏了想到了另一种法法塔处理字符串匹配之类的奇怪技巧(万径人踪灭qwq ...
- 在Android 下写一个检测软件版本号 以自动升级APP 的插件
直接上图上代码: 1.插件类的编写 工程目录结构图: 代码如下: package org.apache.cordova.versionupdate; import org.apache.cordova ...