[APIO2014]序列分割
嘟嘟嘟
复习一下斜率优化,感觉已经忘得差不多了……
这题切入点在与答案跟切的顺序无关。
证明就是假如有三段权值分别为\(x, y, z\),那么这两刀不管按什么顺序切,得到的结果都是\(xy + xz + yz\)。
然后就可以dp。
令\(dp[i][j]\)表示前\(i\)个数切\(j\)刀的最大得分,于是就有\(dp[i][j] = max\{ dp[k][j - 1] + s[k] * (s[i] - s[k]) \}\)。
观察这个式子,发现\(j\)只能从\(j - 1\)转移过来,那索性把\(j\)换到第一维,然后就可以滚动数组省去第一维了,即\(f[i] = max \{ g[k] + s[k] * (s[i] - s[k]) \}\)。
看到乘积,似乎能想到斜率优化。于是假设\(t_2 > t_1\),且\(t_2\)的决策比\(t_1\)优,这时候\(t_1\)就可以扔掉了。那么就有
g[t_2] + s[t_2] * (s[i] - s[t_2]) &\geqslant g[t_1] + s[t_1] * (s[i] - s[t_1]) \\
\frac{(g[t_1] - s[t_1] ^ 2) - (g[t_2] - s[t_2] ^ 2)}{g[t_2] - g[t_1]} &\leqslant s[i]
\end{align*}\]
于是我们用单调队列维护一个下凸壳就好啦。
坑点在于\(s[t_1] = s[t_2]\),这时候斜率直接返回\(-INF\),把\(t_1\)扔出去。
彩蛋:某谷第12个点卡精度,然后我发现乘以\(1.0\)比强制类型转换成double精度要高……
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const ll INF = 1e18;
const db eps = 1e-8;
const int maxn = 2e5 + 5;
const int maxm = 205;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, K;
ll a[maxn];
ll sum[maxn], f[maxn], g[maxn];
int q[maxn], pre[maxn][maxm];
In db slope(int i, int j)
{
if(sum[i] == sum[j]) return -INF;
return 1.0 * ((g[i] - sum[i] * sum[i]) - (g[j] - sum[j] * sum[j])) / ((db)sum[j] - sum[i]);
}
int main()
{
n = read(), K = read();
for(int i = 1; i <= n; ++i) a[i] = read(), sum[i] = sum[i - 1] + a[i];
for(int j = 1; j <= K; ++j)
{
int l = 1, r = 0;
q[++r] = 0;
for(int i = 1; i <= n; ++i)
{
while(l < r && slope(q[l], q[l + 1]) <= sum[i]) ++l;
f[i] = g[q[l]] + sum[q[l]] * (sum[i] - sum[q[l]]);
pre[i][j] = q[l];
while(l < r && slope(q[r - 1], q[r]) >= slope(q[r], i)) --r;
q[++r] = i;
}
memcpy(g, f, sizeof(f));
}
write(f[n]), enter;
for(int j = n, i = K; i; --i) j = pre[j][i], write(j), space; enter;
return 0;
}
[APIO2014]序列分割的更多相关文章
- 【斜率DP】BZOJ 3675:[Apio2014]序列分割
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1066 Solved: 427[Submit][Statu ...
- BZOJ 3675: [Apio2014]序列分割( dp + 斜率优化 )
WA了一版... 切点确定的话, 顺序是不会影响结果的..所以可以dp dp(i, k) = max(dp(j, k-1) + (sumn - sumi) * (sumi - sumj)) 然后斜率优 ...
- bzoj3675[Apio2014]序列分割 斜率优化dp
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3508 Solved: 1402[Submit][Stat ...
- BZOJ_3675_[Apio2014]序列分割_斜率优化
BZOJ_3675_[Apio2014]序列分割_斜率优化 Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了 ...
- 斜率优化入门学习+总结 Apio2011特别行动队&Apio2014序列分割&HZOI2008玩具装箱&ZJOI2007仓库建设&小P的牧场&防御准备&Sdoi2016征途
斜率优化: 额...这是篇7个题的题解... 首先说说斜率优化是个啥,额... f[i]=min(f[j]+xxxx(i,j)) ; 1<=j<i (O(n^2)暴力)这样一个式子,首 ...
- P3648 [APIO2014]序列分割(斜率优化dp)
P3648 [APIO2014]序列分割 我们先证明,分块的顺序对结果没有影响. 我们有一个长度为3的序列$abc$ 现在我们将$a,b,c$分开来 随意枚举一种分块方法,如$(ab)(c)$,$(a ...
- [luogu P3648] [APIO2014]序列分割
[luogu P3648] [APIO2014]序列分割 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序 ...
- 洛谷 P3648 [APIO2014]序列分割 解题报告
P3648 [APIO2014]序列分割 题目描述 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的 ...
- [APIO2014]序列分割 --- 斜率优化DP
[APIO2014]序列分割 题目大意: 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的操作\(k ...
- BZOJ3675 [Apio2014]序列分割 【斜率优化dp】
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 3366 Solved: 1355 [Submit][St ...
随机推荐
- tensorflow机器学习模型的跨平台上线
在用PMML实现机器学习模型的跨平台上线中,我们讨论了使用PMML文件来实现跨平台模型上线的方法,这个方法当然也适用于tensorflow生成的模型,但是由于tensorflow模型往往较大,使用无法 ...
- springboot+springcloud集成jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- mongodb分片扩展架构
目录 一.简介 二.分片集群 三.数据分布策略 四.Mongos访问模式 五.Config元数据 六.分片均衡 参考文档 一.简介 MongoDB目前3大核心优势:『灵活模式』+ 『高可用性』 + 『 ...
- kubernetes的安装方法
背景 自己学习k8s集群,无奈屌丝一枚,没钱配置vpn服务,安装k8s花费的时间太久了.为了小伙伴们可以快速安装k8s,我花了点时间整理了这篇博客,提供一个不用FQ就可以愉快安装k8s集群的方法. 主 ...
- [十三]基础数据类型之AbstractStringBuilder
String内部是一个private final char value[]; 也就意味着每次调用的各种处理方法,返回的字符串都是一个新的,性能上,显然.... 所以,对于可变字符序列的需求是很明确 ...
- eclipse中的.yml和.properties文件没有绿色叶子图标
0.首先确认正确安装了STS插件 要在eclipse使用spring boot创建项目,必须先安装STS(Spring Tool Suite (STS) for Eclipse),如果网速给力的话可以 ...
- ROS笔记1 安装及创建一个ROS Package
安装 跟着官方的安装指引来就行了.安装前要先确定自己的ros版本和ubuntu版本.这二者是一一对应的. http://wiki.ros.org/ROS/Installation 主要是package ...
- MySQL 笔记整理(5) --深入浅出索引(下)
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> 5) --深入浅出索引(下) 这次的笔记从一个简单的查询开始: 建表语句是这样的 mysql> create table T ...
- sprinbcloud学习之-Failed to bind properties under 'logging.level' to java.util.Map<java.lang.String>
日志报错,提示Failed to bind properties under 'logging.level' to java.util.Map<java.lang.String>, 原因为 ...
- 自然底数e的意义是什么?
自然底数e的意义是什么? https://mp.weixin.qq.com/s?__biz=MzA5ODUxOTA5Mg==&mid=2652553811&idx=1&sn=0 ...