Luogu4983 忘情
定义序列 \(x_1,\ x_2,\ \cdots,\ x_n\) 的值为 \(\frac{((\displaystyle\sum_{k=1}^nx_k\times \bar x) + \bar x)^2}{\bar x^2}\)
给定一段序列 \(a_1,\ a_2,\ \cdots,\ a_n\) ,将它分成 \(m\) 段,使每段值的和最小,求这个最小值
\(m\leq n\leq10^5,\ 1\leq a_i\leq1000\)
wqs二分+斜率优化
首先考虑不限制段数,斜率优化即可
原式 \(=(1+\displaystyle\sum_{k=1}^nx_i)^2\)
令 \(s_i=\displaystyle\sum_{k=1}^ia_k\)
列出 \(dp\) 方程 $$f_i=\displaystyle\min_{j<i}{f_j+(s_i-s_j+1)^2}$$
去掉 \(\min\),套路化简得 $$f_j=(2s_i+1)s_j+f_i-s_i^2-2s_i-1$$
然后用单调队列维护下凸包~
然后考虑如何限制段数
感性地理解或者打表观察或者严格的数学证明可以发现:如果我们给每个 \(f_i\) 值都强行加上一个增量 \(w\),因为要最小化 \(f_i\),那么 \(w\) 越大,总段数就会越少
所以我们可以二分这个重物 \(val\),斜率优化做一遍 \(dp\),同时记录一下划分段数 \(c_i\),然后判断划分的总段数\(c_n\) 与 \(m\) 的大小关系。如果 \(cnt_n>m\) 就说明 \(val\) 不够大,要调大。
时间复杂度 \(O(n\log w)\)
代码
#include <bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int maxn = 1e5 + 10;
int n, m, c[maxn], q[maxn]; ll s[maxn], f[maxn];
ll sqr(ll x) { return x * x; }
db slope(int x, int y) {
return db(f[x] - f[y] + sqr(s[x]) - sqr(s[y])) / db(s[x] - s[y]);
}
bool check(ll x) {
int l = 1, r = 1; q[1] = 0;
for (int i = 1; i <= n; i++) {
while (l < r && slope(q[l], q[l + 1]) < 2.0 * (s[i] + 1)) l++;
f[i] = f[q[l]] + sqr(s[i] - s[q[l]] + 1) + x, c[i] = c[q[l]] + 1;
while (l < r && slope(q[r - 1], q[r]) > slope(q[r], i)) r--;
q[++r] = i;
}
return c[n] > m;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld", s + i), s[i] += s[i - 1];
}
ll l = 0, r = sqr(s[n]) + s[n], mid, res;
while (l < r) {
check(mid = l + r >> 1) ? l = mid + 1 : r = res = mid;
}
check(res);
printf("%lld", f[n] - 1ll * res * m);
return 0;
}
Luogu4983 忘情的更多相关文章
- [总结] wqs二分学习笔记
论文 提出问题 在某些题目中,强制规定只能选 \(k\) 个物品,选多少个和怎么选都会影响收益,问最优答案. 算法思想 对于上述描述的题目,大部分都可以通过枚举选择物品的个数做到 \(O(nk^2)\ ...
- P4983忘情
今天挺开心的\(\sim\),省选加油\(!\) \(P4893\)忘情 我能说今晚我才真正学会\(wqs\)和斜率优化吗\(?\) 恰好选几个,必然需要\(wqs\)二分一下 那么考虑不考虑次数情况 ...
- 洛谷T51924 忘情
二分上界有多大开多大 二分上界有多大开多大 二分上界有多大开多大 重要的事情说三遍 又被bright神仙带着做题了 先无脑上wqs二分 我们可以把这个柿子画一下,区间的花费就变成((sigema(l~ ...
- 洛谷P4983 忘情 (WQS二分+斜率优化)
题目链接 忘情水二分模板题,最优解对划分段数的导数满足单调性(原函数凸性)即可使用此方法. 详细题解洛谷里面就有,不啰嗦了. 二分的临界点让人有点头大... #include<bits/stdc ...
- B 最熟悉的陌生人 (纪念当年就读的梅州市江南高级中学)
最熟悉的陌生人 作者:张慧桥 枪与玫瑰 我看了一下聊天室的名单,哈哈哈,我不禁喜出望外:蝶恋花那丫头片子挂在线上呢,真是天助我也.初时的担心一扫而光,我精神抖擞地喝下一大口咖啡,猛抽了三口烟,现在的我 ...
- 详解Bootstrap面板组件
面板组件主要作用是用来处理一些其他组件无法完成的功能,在不同的版本中具有不同的源码: LESS:panels.less SASS:_panels.scss 基础面板非常简单,就是一个div容器中运用了 ...
- [ZZ] Cache
http://blog.sina.com.cn/s/blog_6472c4cc0102duzr.html 处理器微架构访问Cache的方法与访问主存储器有类似之处.主存储器使用地址编码方式,微架构可以 ...
- Linux就这个范儿 第12章 一个网络一个世界
Linux就这个范儿 第12章 一个网络一个世界 与Linux有缘相识还得从一项开发任务说起.十八年前,我在Nucleus OS上开发无线网桥AP,需要加入STP生成树协议(SpanningTree ...
- 奇葩app大盘点,你知道几个
1.I'm Rich 这个App最奇葩.不仅奇葩,还无聊.炫富.浮夸,曾经荣耀一时的"劳资是土豪"应用,售价999.99美元,功能和它的简介一样粗暴,999美元买来的红钻石就是土豪 ...
随机推荐
- Python mysql 创建连接
安装 pymysql 模块 pip3 install pymysql # python2, 默认无 pip 命令 # python3, 默认自带 pip3 命令 mysql基本操作 # 导入 pymy ...
- 2018-10-04 [日常]用Python读取word文档中的表格并比较
最近想对某些word文档(docx)的表格内容作比较, 于是找了一下相关工具. 参考Automate the Boring Stuff with Python中的word部分, 试用了python-d ...
- 在C++的函数中如何指定一个数组,使得这个数组的大小由函数的输入值来决定
今天调试一个C++程序,在一个函数中定义了一个一维数组,设定数组的大小由函数的输入值来决定. 是这样子的: ]; 然后发现:报错! 报错是这样的: 那么问题来了,在C++中定义数组一定要指定数组大小么 ...
- java Web三大组件--监听器
监听器概述 监听器(Listener)是一种特殊的Servlet技术,它可以监听Web应用的上下文信息.Servlet请求信息和Servlet会话信息,即ServletContext.ServletR ...
- JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程
JNI/NDK Java调用C/C++前言 通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...
- button改变某div内文字内容的显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- git 入门教程之变基合并
git 鼓励大量使用分支---"早建分支!多用分支!",这是因为即便创建再多的分支也不会造成存储或内存开销,并且分支的作用有助于我们分解逻辑工作,这样一样其实比维护单一臃肿分支要简 ...
- python 画个小猪佩奇
不知道大家小时候有没有学习过logo语言,就是操纵一只小王八,来画各种图案.博主小学微机课就学习了这个,最近发现python的turtle包就是logo语言,所以画个小猪佩奇和大家分享. 代码来自知乎 ...
- 2016-04-25-信息系统实践手记6-JS调用Flex的性能问题一例
layout: post title: 2016-04-25-信息系统实践手记6-JS调用Flex的性能问题一例 key: 20160425 tags: GIS JS FLEX 技术选型 性能 API ...
- request获取各种路径
equest.getRealPath() 这个方法已经不推荐使用了,代替方法是: request.getSession().getServletContext().getRealPath() 在ser ...