BZOJ3675: [Apio2014]序列分割(斜率优化)
Time Limit: 40 Sec Memory Limit: 128 MB
Submit: 4186 Solved: 1629
[Submit][Status][Discuss]
Description
Input
输入第一行包含两个整数n,k(k+1≤n)。
Output
输出第一行包含一个整数,为小H可以得到的最大分数。
Sample Input
4 1 3 4 0 2 3
Sample Output
HINT
【样例说明】
在样例中,小H可以通过如下3轮操作得到108分:
1.-开始小H有一个序列(4,1,3,4,0,2,3)。小H选择在第1个数之后的位置
将序列分成两部分,并得到4×(1+3+4+0+2+3)=52分。
2.这一轮开始时小H有两个序列:(4),(1,3,4,0,2,3)。小H选择在第3个数
字之后的位置将第二个序列分成两部分,并得到(1+3)×(4+0+2+
3)=36分。
3.这一轮开始时小H有三个序列:(4),(1,3),(4,0,2,3)。小H选择在第5个
数字之后的位置将第三个序列分成两部分,并得到(4+0)×(2+3)=
20分。
经过上述三轮操作,小H将会得到四个子序列:(4),(1,3),(4,0),(2,3)并总共得到52+36+20=108分。
【数据规模与评分】
:数据满足2≤n≤100000,1≤k≤min(n -1,200)。
Source
这题,,做的我,,想骂人
只要你能看出,最终答案与分割顺序无关
然后剩下的就是被卡时间被卡空间被卡精度了******
按照上面说的,首先列出裸的dp方程
$f[i][j]$表示前$i$个分了$j$段,转移的时候枚举从哪里分开
时间复杂度:$O(N^2k)$
考虑优化,设$j>k$且$j$比$k$优
最后可以画为
$$S_{i} >\dfrac {S^{2}_{j}-f_{j}-\left( S^{2}_{x}-f_{k}\right) }{S_{i}-S_{k}}$$
按照套路,发现能斜率优化,然后上模板就行了,单调队列可以滚动掉
这题是我为数不多会做但是不会写代码的题
到最后还没在UOJ上卡过去
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#define LL long long
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[ << ], *p1 = buf, *p2 = buf;
const int MAXN = ;
const LL INF = 1e18 + ;
using namespace std;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, K;
LL a[MAXN], sum[MAXN];
LL f[MAXN][];
int pre[MAXN][], q[MAXN], h, t, now = ;
LL X(int x) {
return sum[x];
}
LL Y(int x) {
return sum[x] * sum[x] - f[x][now ^ ];
}
double slope(int x, int y) {
//printf("%d %d\n", x, y);
if(X(y) == X(x)) return -INF;
return (double)(Y(y) - Y(x)) / (X(y) - X(x));
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
N = read(); K = read();
for(int i = ; i <= N; i++) a[i] = read(), sum[i] = sum[i - ] + a[i]; for(int j = ; j <= K; j++) {
h = t = ; now ^= ;
for(int i = ; i <= N; i++) {
while(h < t && slope(q[h], q[h + ]) <= (double)sum[i]) h++;
int k = q[h];
f[i][now] = f[k][now ^ ] + (sum[i] - sum[k]) * sum[k];
pre[i][j] = k;
while(h < t && (slope(q[t - ], q[t]) >= slope(q[t], i))) --t;
q[++t] = i;
}
}
printf("%lld\n", f[N][now]);
}
BZOJ3675: [Apio2014]序列分割(斜率优化)的更多相关文章
- 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 ...
- 【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...
- P3648 [APIO2014]序列分割 斜率优化
题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
- [Bzoj3675][Apio2014]序列分割(斜率优化)
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4021 Solved: 1569[Submit][Stat ...
- BZOJ3675 [Apio2014]序列分割 【斜率优化dp】
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 3366 Solved: 1355 [Submit][St ...
- BZOJ3675 [Apio2014]序列分割 动态规划 斜率优化
原文链接http://www.cnblogs.com/zhouzhendong/p/8697258.html 题目传送门 - BZOJ3675 题意 对于一个非负整数序列,小H需要重复k次以下的步骤: ...
- 【BZOJ3675】【APIO2014】序列分割 [斜率优化DP]
序列分割 Time Limit: 40 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 小H最近迷上了一个分隔序列的游戏. ...
随机推荐
- js中常见面试问题-笔记
原文参考https://mp.weixin.qq.com/s/mCVL6qI33XeTg4YGIKt-JQ 1.事件代理给父元素添加事件,利用事件冒泡原理,在根据e.target来获取子元素<u ...
- 怎么区分odd和even
odd [ɒd] 和even ['iːv(ə)n] 一个表示奇数.一个表示偶数 经常混淆. 一个记住的好方法: odd是3个字母,单数,所以表示奇数 even是4个字母,所以表示偶数
- margin的auto的理解 top,left[,bottom,right] position
auto auto 总是试图充满父元素 margin有四个值: All the margin properties can have the following values: auto - the ...
- javascript tips and snippets
如何给javascript对象动态创建动态key // ES2015 var key = 'DYNAMIC_KEY', obj = { [key]: 'ES6!' }; console.log(obj ...
- 【设计模式最终总结】桥接模式 VS 外观模式
差异点 外观模式,是把功能通过一个接口提供出来,方便日后更换实现,或者这种实现可以由多方提供,但同时只用一个.典型例子:@Slf4j 桥接模式,多个维度,每个维度提供一个接口,这些接口集中在一个类中, ...
- February 2 2017 Week 5 Thursday
Only do what your heart tells you. 随心而行. My heart tells me that I should leave here and go back to X ...
- 如何跟踪比特币SV(BSV)地址余额?
Coin Balance Tracker 能够查看任何BSV/BCH/BTC地址的当前余额.您只需要确保你的电脑能连接Internet以及地址正确.此程序非常安全,因为它只使用公共数据,不需要登录和密 ...
- java学习第一步,使用IntelliJ IDEA编写自己的第一个java程序
首先下载java的jdk,然后说一下IDEA的配置 IntelliJ IDEA目前公认的最好的java开发工具,不过一般的学校的教学还是使用eclipse来进行java的开发.所以老师一般只会教你如何 ...
- 理解Underscore中的_.template函数
Underscore中提供了_.template函数实现模板引擎功能,它可以将JSON数据源中的数据对应的填充到提供的字符串中去,类似于服务端渲染的模板引擎.接下来看一下Underscore是如何实现 ...
- io操作的要素
文件 操作. 操作说明 数据