P3648 [APIO2014]序列分割(斜率优化dp)
我们先证明,分块的顺序对结果没有影响。
我们有一个长度为3的序列$abc$
现在我们将$a,b,c$分开来
随意枚举一种分块方法,如$(ab)(c)$,$(a)(b)(c)$
答案为$(a+b)*c+a*b=ac+bc+ab$
多枚举几种,我们发现答案总是不变的。
所以我们可以默认每次从左到右扫,用dp求解
对于每个$1$到$k$,我们都把序列扫一遍
设$f[k][i]$为对前$i$个数进行$k$次切割的最大价值,
$s[i]$为元素前缀和,那么
$f[k][i]=f[k-1][j]+s[j]*(s[i]-s[j])$
这个$k$显然是可以滚动优化掉的,设滚动数组为$g[i]$
$f[i]=g[j]+s[j]*(s[i]-s[j])$
$g[j]-s[j]^{2}=-s[i]*s[j]+f[i]$
又化成了我们熟悉的$y=kx+b$
$y=g[j]-s[j]^{2}$
$k=-s[i]$
$x=s[j]$
$b=f[i]$
$x,k$单调递增,于是我们直接上单调队列维护下凸包就好辣
顺带再开个数组记录一下路径就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#define rint register int
using namespace std;
typedef long long ll;
#define N 100005
ll s[N],f[N],g[N];
int n,k,L,R,h[N],p[][N];
inline ll X(int x){return s[x];}
inline ll Y(int x){return g[x]-s[x]*s[x];}
inline ll KK(ll xa,ll ya,ll xb,ll yb){return ya*xb-yb*xa;}
int main(){
scanf("%d%d",&n,&k);
for(rint i=;i<=n;++i)
scanf("%lld",&s[i]),s[i]+=s[i-];
for(rint j=;j<=k;++j){
h[L=R=]=;
for(rint i=;i<=n;++i){
while(L<R&&KK(X(h[L+])-X(h[L]),Y(h[L+])-Y(h[L]),,-s[i])>=) ++L;
f[i]=g[h[L]]+(s[i]-s[h[L]])*s[h[L]]; p[j][i]=h[L];
while(L<R&&KK(X(h[R])-X(i),Y(h[R])-Y(i),X(h[R])-X(h[R-]),Y(h[R])-Y(h[R-]))<=) --R;
h[++R]=i;
}swap(g,f);
}
printf("%lld\n",g[n]);//注意答案在g上
for(rint i=k,d=p[k][n];i;--i,d=p[i][d]) printf("%d ",d);
return ;
}
P3648 [APIO2014]序列分割(斜率优化dp)的更多相关文章
- 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次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
- BZOJ 3675 APIO2014 序列切割 斜率优化DP
题意:链接 方法:斜率优化DP 解析:这题BZ的数据我也是跪了,特意去网上找到当年的数据后面二十个最大的点都过了.就是过不了BZ. 看到这道题自己第一发DP是这么推得: 设f[i][j]是第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首 ...
随机推荐
- [原][openstack-pike][controller node][issue-3][horizon] dashboard show internal error 500 Cannot serve directory /var/www/html
问题点: 安装完pike后发现只能使用 ip:80 登录到http的主页面 不能使用 http://controller_ip:80/dashboard 登录openstack登录页面.如下图 重启h ...
- Python Django 配置QQ邮箱发送邮件
一.实验环境 Python2.7 + Django1.10.0 二.获取QQ邮箱授权码 1.什么是授权码? 授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码. 适用于登录以下服务:POP3/IM ...
- linux下的ssh和rynsc
在ubuntu下有ssh的目录,但是没有使用 ps -e | grep ssh时没有任何输出,说明没有安装ssh或者是1.x版本,可以打开etc/ssh目录,看是否有文件,下装系统再看看吧.还有ryn ...
- java生成excel,word文件
第一部分: 在网站开发中,用户可能需要打印word或者excel表,这种需求是非常多的. java语言生成excel表格和python的方式有点像,使用Apache POI的组件,一通全通.开发过程通 ...
- python获取两个日期间的工作日
import datetime # 计算两个日期之间的工作日数,非天数. class workDays(): def __init__(self, start_date, end_date, days ...
- 解决mapper绑定异常:nested exception is org.apache.ibatis.binding.BindingException:
原因: 此异常的原因是由于mapper接口编译后在同一个目录下没有找到mapper映射文件而出现的.由于maven工程在默认情况下src/main/java目录下的mapper文件是不发布到targe ...
- sourceTree回退撤销commit
https://blog.csdn.net/gang544043963/article/details/71511958
- Python_环境部署及报错汇总(0)
一.安装Anaconda Anaconda是一个开源的包.环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换. Anaconda包括Conda.Python以及 ...
- cestos7安装zookeeper
zookeeper安装包下载地址http://archive.apache.org/dist/zookeeper/ 一.单机 在/usr目录下 curl -L-O http://archive.apa ...
- python使用MySQLdb实现连接数据库Mysql
python实现连接数据库mysql的步骤: 一.引入MySQLdb 二.获取与数据库的连接 三.执行SQL语句和存储过程 四.关闭数据库连接 1.什么是MySQLdb? MySQLdb是用于pyth ...