[APIO2014]序列分割 --- 斜率优化DP
[APIO2014]序列分割
题目大意:
你正在玩一个关于长度为\(n\)的非负整数序列的游戏。这个游戏中你需要把序列分成\(k+1\)个非空的块。为了得到\(k+1\)块,你需要重复下面的操作\(k\)次:
选择一个有超过一个元素的块(初始时你只有一块,即整个序列)
选择两个相邻元素把这个块从中间分开,得到两个非空的块。
每次操作后你将获得那两个新产生的块的元素和的乘积的分数。你想要最大化最后的总得分。
\(n<=10^{5},k<=200\)
首先划分完\(k\)块后,发现非常像线性DP模型
自然地想,是不是分数跟划的顺序无关?
可以证明是的(归纳法)
那么,设
\(dp(i,j)\)表示枚举到了\(i\),第\(1...i\)切了几刀的最大收益。
有\(dp(i,j)=max(dp(k,j-1)+sum[k]*(sum[i]-sum[k]))(1<=k<=i-1)\)
那么展开式子,化为斜率优化的式子:
\(-dp(k,j-1)=sum[k]*sum[i]-sum[k]^{2}-dp(i,j)\)
其中\(k\)为\(sum[k]\),单调递增
其中\(x\)为\(sum[i]\),单调递增
要使\(dp(i,j)\)最大,因此维护下凸包,那么可以使用单调队列
空间滚一下就好
空间复杂度:\(O(n)\)(忽略记录决策点)
时间复杂度:\(O(nk)\)
注:被宏定义坑了很久。。。
#include<cstdio>
#include<cstring>
#define sid 100050
#define dd double
#define ll long long
#define ri register int
using namespace std; #define getchar() *S ++
char RR[], *S = RR;
inline int read(){
int p = , w = ;
char c = getchar();
while(c > '' || c < '') {
if(c == '-') w = -;
c = getchar();
}
while(c >= '' && c <= '') {
p = p * + c - '';
c = getchar();
}
return p * w;
} ll sum[sid], dp[][sid];
int lst[][sid], q[sid], n, k;
bool now = , pre = ; #define x(g) sum[(g)]
#define y(g) (sum[(g)]*sum[(g)]-dp[pre][(g)])
inline dd s(int i, int j) {
if(x(i) == x(j)) return -1e18;
return (dd)(y(i) - y(j)) / (dd)(x(i) - x(j));
} int main() {
fread(RR, , sizeof(RR), stdin);
n = read(); k = read();
for(ri i = ; i <= n; i ++) sum[i] = sum[i - ] + read();
for(ri j = ; j <= k; j ++) {
int fr = , to = ; now ^= ; pre ^= ;
for(ri i = ; i <= n; i ++) {
while(fr + <= to && s(q[fr], q[fr + ]) <= sum[i]) fr ++;
dp[now][i] = dp[pre][q[fr]] + sum[q[fr]] * (sum[i] - sum[q[fr]]);
lst[j][i]=q[fr];
while(fr + <= to && s(q[to - ], q[to]) >= s(q[to], i)) to --;
q[++ to] = i;
}
}
printf("%lld\n",dp[now][n]);
int e = n;
for(ri i = k; i >= ; i --) {
e = lst[i][e]; printf("%d ", e);
}
return ;
}
序列分割
[APIO2014]序列分割 --- 斜率优化DP的更多相关文章
- bzoj3675[Apio2014]序列分割 斜率优化dp
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3508 Solved: 1402[Submit][Stat ...
- 【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
- BZOJ 3675 APIO2014 序列切割 斜率优化DP
题意:链接 方法:斜率优化DP 解析:这题BZ的数据我也是跪了,特意去网上找到当年的数据后面二十个最大的点都过了.就是过不了BZ. 看到这道题自己第一发DP是这么推得: 设f[i][j]是第j次分第i ...
- P3648 [APIO2014]序列分割 斜率优化
题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...
- 【BZOJ3675】【APIO2014】序列分割 [斜率优化DP]
序列分割 Time Limit: 40 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 小H最近迷上了一个分隔序列的游戏. ...
- BZOJ3675: [Apio2014]序列分割(斜率优化)
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4186 Solved: 1629[Submit][Status][Discuss] Descript ...
- BZOJ 3675: 序列分割 (斜率优化dp)
Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...
- BZOJ 3675: [Apio2014]序列分割( dp + 斜率优化 )
WA了一版... 切点确定的话, 顺序是不会影响结果的..所以可以dp dp(i, k) = max(dp(j, k-1) + (sumn - sumi) * (sumi - sumj)) 然后斜率优 ...
随机推荐
- ADO.NET中带参数的Sql语句的陷阱
1.使用Parameter //利用构造函数方式 ,不推荐这样写 Parameter p =new Parameter("@id",值); cmd.Parameters.Add(p ...
- 旅游(CSUST省赛选拔赛2+状压dp+最短路)
题目链接:http://csustacm.com:4803/problem/1016 题目: 思路:状压dp+最短路,比赛的时候有想到状压dp,但是最短路部分写挫了,然后就卡死了,对不起出题人~dis ...
- Android 搭建Linux系统
本文精心从网上搜罗出相关资料并整理,含有大量外部链接 安卓手机上安装linux大致分为两种方案 一.使用Linux Deploy 二.使用 Linux on Android 本文对Linux Depl ...
- 项目开发 -- ZFS容量分配
存储池 allocated 池中已实际分配的存储空间量.该属性也可通过其简短列名alloc来引用. capacity 已用的池空间百分比.此属性也可通过其简短列名cap来引用. dedupratio ...
- Big O
评价一个计算机算法的效率时用到的方法我们称之为Big O(Order of [大约是]). 有序二分查找算法: 比如我们通过二分查找算法查找容器里的10个数据. 那么,我们需要查找一个数据时正常应该是 ...
- makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解【转】
转自:http://www.cnblogs.com/lifexy/p/7065175.html 在linux中输入vi Makefile 来实现创建Makefile文件 注意:命令行前必须加TAB键 ...
- linux 内核信号量
Linux内核的信号量在概念和原理上和用户态的System V的IPC机制信号量是相同的,不过他绝不可能在内核之外使用,因此他和System V的IPC机制信号量毫不相干. 信号量在创建时需要设置一个 ...
- 15个你不得不知道的Chrome dev tools的小技巧
转载自:https://www.imooc.com/article/2559 谷歌浏览器如今是Web开发者们所使用的最流行的网页浏览器.伴随每六个星期一次的发布周期和不断扩大的强大的开发功能,Chro ...
- ubuntu无法获得锁 /var/lib/dpkg -open 问题
问题: 方法: sudo rm /var/lib/dpkg/lock 然后再安装就可以了
- cocos2d-x android 添加新场景报错: undefined reference to `vtable for XXX'
转载自 居家懒人 http://www.cnblogs.com/JD85/archive/2012/09/17/2688128.html 加入写了新场景SecondScene,结果在cpp文件里类名地 ...