luoguP3648 [APIO2014]序列分割
https://www.luogu.org/problemnew/show/P3648
同bzoj3675
这题斜率优化+滚动数组就可以了qwq
因为我是在飞机上瞎bb的式子,所以可能会和别的题解的式子不一样(反正 A 题了对吧)
推的过程什么的都写在最底下的注释里了,大家可以选择先查看最底下的过程(您是神犇可以不用看这篇博客)
但这篇题解不知为什么在bzoj上过不了,请dalao们赐教
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &f) {
f = 0; T fu = 1; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') fu = -1; c = getchar();}
while (c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
}
typedef long long ll;
const int N = 100000 + 10;
const int M = 200 + 10;
ll f[2][N], s[N], a[N];
int fr[M][N], q[N], ans[N], head, tail;
int n, m;
bool pd(int a, int b, int c, int d) {
// g(b, c) >= s[n] - s[d]
// (f[b] - f[c]) / (s[b] - s[c]) >= s[n] - s[d]
if(f[a][b] - f[a][c] <= (s[b] - s[c]) * (s[n] - s[d])) return 1;
return 0;
}
bool pd2(int a, int b, int c, int d) {
// g(b, c) < g(c, d)
// (f[b] - f[c]) / (s[b] - s[c]) < (f[c] - f[d]) / (s[c] - s[d])
// (f[b] - f[c]) * (s[c] - s[d]) < (f[c] - f[d]) * (s[b] - s[c])
if((f[a][b] - f[a][c]) * (s[c] - s[d]) < (f[a][c] - f[a][d]) * (s[b] - s[c])) return 1;
return 0;
}
int main() {
read(n); read(m);
for(int i = 1; i <= n; i++) {
read(a[i]);
s[i] = s[i - 1] + a[i];
}
for(int i = 1; i <= m; i++) {
head = 0, tail = 0; q[0] = i - 1;
for(int j = i; j <= n; j++) {
// 保证队列里有两个元素
while(head + 1 <= tail) {
if(pd((i & 1) ^ 1, q[head], q[head + 1], j)) head++;
else break;
}
f[i & 1][j] = f[(i & 1) ^ 1][q[head]] + (s[n] - s[j]) * (s[j] - s[q[head]]);
fr[i][j] = q[head];
while(head + 1 <= tail) {
if(pd2((i & 1) ^ 1, q[tail - 1], q[tail], j)) tail--;
else break;
}
q[++tail] = j;
}
}
ll maxn = -1; int num;
for(int i = n; i >= m; i--) if(f[m & 1][i] > maxn) maxn = f[m & 1][i], num = i;
printf("%lld\n", maxn);
for(int i = m; i >= 1; i--) {
ans[i] = num;
num = fr[i][num];
}
for(int i = 1; i < m; i++) printf("%d ", ans[i]);
printf("%d\n", ans[m]);
return 0;
}
// f[i] 表示取到了第 i 个数获得的最大价值
// f[i] = f[j] + (s[n] - s[i]) * (s[i] - s[j])
// f[i] = f[j] + s[n] * s[i] - s[n] * s[j] - s[i] * s[i] + s[i] * s[j]
// 假设 j 比 k 优, j < k
// f[j] + s[n] * s[i] - s[n] * s[j] - s[i] * s[i] + s[i] * s[j] > f[k] + s[n] * s[i] - s[n] * s[k] - s[i] * s[i] + s[i] * s[k]
// f[j] - s[n] * s[j] + s[i] * s[j] > f[k] - s[n] * s[k] + s[i] * s[k]
// f[j] - s[j] * (s[n] - s[i]) > f[k] - s[k] * (s[n] - s[i])
// f[j] - f[k] > (s[j] - s[k]) * (s[n] - s[i])
// (f[j] - f[k]) / (s[j] - s[k]) < s[n] - s[i]
// 令 g(i, j) 表示 i 和 j 的斜率
// i < j < k
// if g(i, j) < g(j, k)
// if g(i, j) < s[n] - s[x] j 比 i 差
// if g(i, j) >= s[n] - s[x] i 比 j 差, j 比 k 差
// 所以 j 就被扔掉了 QAQ
// 令 a, b 为队首两点
// if g(a, b) >= s[n] - s[i]
// a 比 b 差
// 当 i 上升时, s[n] - s[i] 单调不增
// a 永远比 b 差
// 飞机上没有博客只能自己推式子好痛苦啊 QAQ
luoguP3648 [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 ...
随机推荐
- Python 正则表达式之选择
In [4]: import re In [5]: re.findall(r"\d+","jjj1234mm222")Out[5]: ['1234', '222 ...
- Java面向对象-面向对象编程之基本概念
面向对象这个概念,每本书上的说法定义很多. 我自己根据我的经验,自己归档总结了下, 所谓面向对象,就是 以基于对象的思维去分析和解决问题,万物皆对象: 面向对象经常和面向过程放一起讨论: 这里举例, ...
- 「小程序JAVA实战」微信小程序工程结构了解(五)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-05/ 微信小程序工程结构 audio,button,canvas,checkbox 都是由4个文件 ...
- 华为部分真机调试无法显示log问题解决
真机测试时,部分华为手机无法获取全部的log信息.或者说无法获取Error以下级别的log信息.比如P7 这是因为部分华为机出厂默认log设置为关闭状态,因此只能获取Error以上级别的log信息.蛋 ...
- React 常用面试题目与分析
调用 setState 之后发生了什么? 在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation).经过调和过程 ...
- 【283】ArcMap 中河流字体设置
左斜字体的设置 1. 右键属性设置如下,将字体角度如下设置,并点击改变样式的按钮 2. 首先设置颜色如下,然后设置加粗斜体,最后勾选 CJK character orientation 的复选框 C ...
- 12个有趣的c语言面试题
1.gets()函数 问:请找出下面代码里的问题: #include int main(void) { char buff[10]; memset(buff,0,sizeof(buff)); gets ...
- Linux的基本指令--其他命令
一 . 终端翻页: shift-pageup shift-pagedown 二 . 看手册:man man man 2 read 查看read系统函数的man page(在第二个section中,表示 ...
- Mac hook—DYLD_INSERT_LIBRARIES
[Mac hook—DYLD_INSERT_LIBRARIES] 1.gcc生成dylib. gcc -dynamiclib -o mysharedlib.dylib mysharedlib.c 2. ...
- 使用DevStack安装openstack(单机环境)
DevStack是一系列可扩展的脚本,用于根据git master的最新版本快速启动完整的OpenStack环境.它以交互方式用作开发环境,并作为OpenStack项目功能测试的基础. 参考源码. 警 ...