传送门

斜率优化dp经典题目。

首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的。

根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立。

我们设两个断点分成的三段连续序列的和为a,b,ca,b,ca,b,c

如果先分左边有:total=a∗(b+c)+b∗c=a∗b+b∗c+c∗atotal=a*(b+c)+b*c=a*b+b*c+c*atotal=a∗(b+c)+b∗c=a∗b+b∗c+c∗a

如果先分右边有:total=(a+b)∗c+a∗b=a∗b+b∗c+c∗atotal=(a+b)*c+a*b=a*b+b*c+c*atotal=(a+b)∗c+a∗b=a∗b+b∗c+c∗a

是相同的。

那么这样我们就可以按从左到右划分断点的思路来进行dp了。

令f[i][j]f[i][j]f[i][j]为前j个数i个断点能够划分出的最大值。

那么显然有:

f[i]=maxf[i]=maxf[i]=max{f[j]+sum[j]∗(sum[i]−sum[j])f[j]+sum[j]*(sum[i]-sum[j])f[j]+sum[j]∗(sum[i]−sum[j])}

f[i]=maxf[i]=maxf[i]=max{f[j]−sum[j]2f[j]-sum[j]^2f[j]−sum[j]2}+sum[i]∗sum[j]+sum[i]*sum[j]+sum[i]∗sum[j]

if(k1&lt;k2if(k1&lt;k2if(k1<k2&&calc(k1)≤calc(k2))calc(k1)\le calc(k2))calc(k1)≤calc(k2))队头出队

=>f[k1]−sum[k1]2+sum[i]∗sum[k1]≤f[k2]−sum[k2]2+sum[i]∗sum[k2]f[k1]-sum[k1]^2+sum[i]*sum[k1]\le f[k2]-sum[k2]^2+sum[i]*sum[k2]f[k1]−sum[k1]2+sum[i]∗sum[k1]≤f[k2]−sum[k2]2+sum[i]∗sum[k2]

=>f[k1]−sum[k1]2−f[k2]+sum[k2]2≤(sum[k2]−sum[k1])∗sum[i]f[k1]-sum[k1]^2-f[k2]+sum[k2]^2\le (sum[k2]-sum[k1])*sum[i]f[k1]−sum[k1]2−f[k2]+sum[k2]2≤(sum[k2]−sum[k1])∗sum[i]

=>((f[k1]−sum[k1]2)−(f[k2]−sum[k2]2))/(sum[k2]−sum[k1]≤sum[i]((f[k1]-sum[k1]^2)-(f[k2]-sum[k2]^2))/(sum[k2]-sum[k1]\le sum[i]((f[k1]−sum[k1]2)−(f[k2]−sum[k2]2))/(sum[k2]−sum[k1]≤sum[i]

队尾出队:slope(q[tl−1],q[tl])&gt;=slope(q[tl],i)slope(q[tl-1],q[tl])&gt;=slope(q[tl],i)slope(q[tl−1],q[tl])>=slope(q[tl],i)

代码:

#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
inline ll read(){
	ll ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n,K,hd,tl,q[N],tmp;
ll f[2][N],sum[N];
inline ll calcX(int i,int j){return sum[j]-sum[i];}
inline ll calcY(int i,int j){return (f[tmp^1][i]-sum[i]*sum[i])-(f[tmp^1][j]-sum[j]*sum[j]);}
int main(){
	n=read(),K=read(),tmp=0;
	for(int i=1;i<=n;++i)sum[i]=sum[i-1]+read();
	for(int i=1;i<=K;++i){
		hd=tl=1;
		for(int j=1;j<=n;++j){
			while(hd<tl&&calcY(q[hd],q[hd+1])<=calcX(q[hd],q[hd+1])*sum[j])++hd;
			int k=q[hd];
			f[tmp][j]=f[tmp^1][k]+sum[k]*(sum[j]-sum[k]);
			while(hd<tl&&calcY(q[tl-1],q[tl])*calcX(q[tl],j)>=calcY(q[tl],j)*calcX(q[tl-1],q[tl]))--tl;
			q[++tl]=j;
		}
		tmp^=1;
	}
	printf("%lld",f[tmp^1][n]);
	return 0;
}

2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)的更多相关文章

  1. bzoj3675[Apio2014]序列分割 斜率优化dp

    3675: [Apio2014]序列分割 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3508  Solved: 1402[Submit][Stat ...

  2. 【bzoj3675】[Apio2014]序列分割 斜率优化dp

    原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...

  3. [APIO2014]序列分割 --- 斜率优化DP

    [APIO2014]序列分割 题目大意: 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的操作\(k ...

  4. BZOJ3675: [Apio2014]序列分割(斜率优化)

    Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 4186  Solved: 1629[Submit][Status][Discuss] Descript ...

  5. BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)

    洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...

  6. P3648 [APIO2014]序列分割 斜率优化

    题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...

  7. 2018.09.07 codeforces311B. Cats Transport(斜率优化dp)

    传送门 斜率优化dp好题. 对于第i只猫,显然如果管理员想从出发开始刚好接到它,需要在t[i]=h[i]−dist(1,i)" role="presentation" s ...

  8. BZOJ 3675 APIO2014 序列切割 斜率优化DP

    题意:链接 方法:斜率优化DP 解析:这题BZ的数据我也是跪了,特意去网上找到当年的数据后面二十个最大的点都过了.就是过不了BZ. 看到这道题自己第一发DP是这么推得: 设f[i][j]是第j次分第i ...

  9. 【BZOJ3675】【APIO2014】序列分割 [斜率优化DP]

    序列分割 Time Limit: 40 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 小H最近迷上了一个分隔序列的游戏. ...

随机推荐

  1. Centos LVM 创建 删除 扩大 缩小

    新建LVM的过程1.使用fdisk 新建分区 修改ID为8e3.使用 pvcreate 创建 PV 4.使用 vgcreate 创建 VG 5.使用 lvcreate 创建 LV 6.格式化LV7.挂 ...

  2. indy字符编码

    以前是TEncoding.Unicode 现在是IndyTextEncoding_Default

  3. Git----分支管理之创建与合并分支02

    在版本回退里,你已经知道 ,每次提交,Git都把它们串i成一条时间线,这条时间线就是一个分支,截至到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支,HEAD严格来说不是指向提交 ...

  4. websocket使用

    兼容性介绍 : https://caniuse.com/#search=websockets var websocket = null; //判断当前浏览器是否支持WebSocket if ('Web ...

  5. mysql查看进程

    select * from information_schema.processlist 查询所有连接到数据库的进程信息.

  6. mongodb基础学习13-聚集aggregate操作

    aggregate可以用的操作与sql的对应关系 下面来看具体操作例子: 分组求和: 求总记录数 商品价格大于50记录分组求和 商品价格大于50且分组记录大于2的分组记录条件 分组库存数,并按库存排序 ...

  7. Haskell语言学习笔记(53)Data.Sequence

    Data.Sequence Prelude> import Data.Sequence as Seq Prelude Seq> :set -XOverloadedLists Prelude ...

  8. python 日期格式

    %a 星期几的简写%A 星期几的全称%b 月分的简写%B 月份的全称%c 标准的日期的时间串%C 年份的后两位数字%d 十进制表示的每月的第几天%D 月/天/年%e 在两字符域中,十进制表示的每月的第 ...

  9. linux一些基本常识(三)

    acl:对本身权限的扩展    打包:zip 111.zip a.txt b.txt.....    zip -r /etc/sysconfig/* (样才能第归所有内容0)    解宝:uzip 1 ...

  10. IntelliJ IDEA SVN

    第一步:下载svn的客户端,通俗一点来说就是小乌龟啦!去电脑管理的软件管理里面可以直接下载,方便迅速 下载之后直接安装就好了,但是要注意这里的这个文件也要安装上,默认是不安装的,如果不安装,svn中的 ...