Description

  
  传送门
  
  
  
    
  

Solution

  
​  之前我也遇到过一次这种“两段之和乘积作为贡献“的问题:考虑把这一种\((\sum) *(\sum)\)的形式拆括号,就可以发现贡献其实就是分别处于左右的两两元素乘积之和。
  
​  题目的分割\(k\)次,其实就是要你把序列分成\(k+1\)段。
  
​  再考虑在题目中如此的分割方法下,贡献是怎么产生的。对于每一个元素\(a_i\),每次分割时,若涉及到自己,则会贡献一定的乘积\(a_i(\sum)\)。细心想一想就会发现,这个\(\sum\)的总值就是在最终方案下不处于\(a_i\)所在段的元素之和。
  
  单向考虑每一项乘积,(这里有点跳)总的来算,每一段\([l,r]\)的贡献就是\((\sum_{i=l}^ra_i)(\sum_{i=1}^{l-1}a_i)\)。记\(a\)的前缀和为\(s\),则贡献是\((s_r-s_{l-1})s_{l-1}\).
  
  我们可以写出DP式,\(f_{i,j}\)表示前\(i\)个数恰好分成\(j\)段的贡献最大值:
\[ f_{i,j}=\max\{f_{k,j-1}+(s_i-s_k)s_k\}\;\;(k<i) \]
   
  
  直接DP是\(\mathcal O((k+1)n^2)\)的。而看到这个式子比较简单,考虑斜率优化。这里省去第二维,整体做\(k+1\)次即可。
  
​  设\(k<j<i\),\(j\)比\(k\)优,则有:
\[ \begin{aligned} f_j+(s_i-s_j)s_j&>f_{k}+(s_i-s_k)s_k\\ f_j+s_is_j-s_j^2&>f_k+s_is_k-s_k^2\\ s_i(s_j-s_k)&>(s_j^2-f_j)-(s_k^2-f_k)\\ \frac{(s_j^2-f_j)-(s_k^2-f_k)}{(s_j-s_k)}&<s_i \end{aligned} \]
  直接做就可以了。
  
  
  
  
  

Code

  

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int N=100005;
const ll INF=1LL<<62;
const double EPS=1e-6;
int n,m,a[N];
int q[N],head,tail;
ll s[N],real_f[N],real_g[N],*f=real_f,*g=real_g;
inline double slope(int a,int b){return 1.0*((s[b]*s[b]-g[b])-(s[a]*s[a]-g[a]))/(s[b]-s[a]);
}
int main(){scanf("%d%d",&n,&m);int cnt=0;for(int i=1,x;i<=n;i++){scanf("%d",&x);if(x)cnt++,s[cnt]=s[cnt-1]+x;}n=cnt; m=min(m,n-1)+1;for(int j=2;j<=m;j++){q[head=tail=1]=j-1;for(int i=j;i<=n;i++){while(head<tail&&slope(q[head],q[head+1])-EPS<s[i]) head++;int best=q[head];f[i]=g[best]+(s[i]-s[best])*s[best];    while(head<tail&&slope(q[tail-1],q[tail])>slope(q[tail],i)) tail--;q[++tail]=i;}swap(f,g);}printf("%lld\n",g[n]);return 0;
}

转载于:https://www.cnblogs.com/RogerDTZ/p/9248746.html

【BZOJ3675】【Apio2014】序列分割相关推荐

  1. BZOJ3675: [Apio2014]序列分割

    BZOJ3675: [Apio2014]序列分割 Description 小H最近迷上了一个分隔序列的游戏. 在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列. 为了得到k ...

  2. BZOJ3675 [APIO2014]序列分割

    Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...

  3. 动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割

    Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小 ...

  4. 【洛谷3648】[APIO2014] 序列分割(斜率优化DP)

    点此看题面 大致题意: 你可以对一个序列进行\(k\)次分割,每次得分为两个块元素和的乘积,求总得分的最大值. 区间\(DPor\)斜率优化\(DP\) 这题目第一眼看上去感觉很明显是区间\(DP\) ...

  5. [APIO2014] 序列分割(斜率优化dp)

    problem luogu-P3648 你正在玩一个关于长度为 nnn 的非负整数序列的游戏.这个游戏中你需要把序列分成 k+1k+1k+1 个非空的块. 为了得到 k+1k+1k+1 块,你需要重复 ...

  6. 洛谷P3648 [APIO2014]序列分割(斜率优化)

    传送门 没想到这种多个状态转移的还能用上斜率优化--学到了-- 首先我们可以发现,切的顺序对最终答案是没有影响的 比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得 ...

  7. bzoj 3675: [Apio2014]序列分割

    (一开始决策单调性证错了..(蛋疼)(其实是没有单调性的,怎么都一样),可以自己写一写i<j,先分i后分j,和先分j后分i是一样的) (而且犇蒟蒻发现斜率优化随便推上一个式子就可以了,(感觉比D ...

  8. (APIO2014)序列分割

    题解: 我也不知道为啥上午上课讲了我昨天看的3题 这题关键在于发现操作顺序无关的 可以发现最终答案是任意两段乘积的和 那这个东西显然是可以dp的 然后可以斜率优化一波 nklongn 另外上课讲的是当 ...

  9. P3648-[APIO2014]序列分割【斜率优化】

    正题 题目链接:https://www.luogu.com.cn/problem/P3648 题目大意 nnn个数字的序列,分割kkk次,每次的权值是左右两块数字的乘积.求最大权值和分割方案. 解题思 ...

最新文章

  1. 价值2950亿美元的「量子霸权」,技术水平到了哪个阶段
  2. 新工科教育的实践与思考——曾勇校长在工程教育高峰论坛上的报告
  3. 10本计算机视觉必读经典图书,入门篇 + 提升篇
  4. 高等数学:第十二章 微分方程(1)微分方程的概念,可分离变量的微分方程,齐次方程
  5. 如何在C语言中使用正则表达式
  6. pro缺点和不足 一加7t_2021年元旦有哪些一加手机值得购买?
  7. 开发大会上,前微软CEO放出的狠话!.NET开发随时起飞,你准备好了吗?
  8. P5024 保卫王国
  9. java frame清除控件_java – 清除JFrame的组件并添加新组件
  10. 2009年度工作安排计划
  11. sqoop导出到mysql中文乱码问题总结、utf8、gbk
  12. 发力多人在线游戏!PS5有望2020年E3展会亮相!
  13. 数据库系统及应用——班级管理系统
  14. 算法竞赛入门经典(第二版)答案——第一部分
  15. mysql中如何批量删除冗余数据库_WordPress清理数据库中的冗余数据加速网站运行速度...
  16. 谷歌身份验证器电脑版 Google Authenticator下载+使用教程
  17. (微信,支付宝)小程序头像上传选择裁剪区域
  18. python应用程序无法正常启动0xc000007b_应用程序无法正常启动0xc000007b怎么解决
  19. 2022MRCTF-wp
  20. winows10和centos 双系统 安装记录

热门文章

  1. 系统学习 TypeScript(二)——开发流程和语法规则
  2. NFS还是iSCSI?关于VMware vSphere的存储连接的选择题
  3. mysql 单向自动同步_mysql单向自动同步
  4. ArcGIS制图表达Representation实战篇3-控制点
  5. 浅谈 OpenResty
  6. 【java学习之路】(javaWeb篇)002.CSS
  7. 【java学习之路】(java SE篇)008.集合
  8. html5 过渡时间,CSS3 对过渡(transition)进行调速以及延时
  9. fuelux.tree,动态加载
  10. Hive insert into小文件问题优化解决