传送门

斜率优化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. ajax 实现跨域

    ajax本身是不可以跨域的,通过产生一个script标签来实现跨域.因为script标签的src属性是没有跨域的限制的. 其实设置了dataType: 'jsonp'后,$.ajax方法就和ajax ...

  2. 在spring引入log4j(非web项目)

    https://blog.csdn.net/u012578322/article/details/78012183 在spring中使用log4j 引入log4j软件包 配置log4j属性 加载log ...

  3. 4 并发编程-(进程)-守护进程&互斥锁

    一.守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,崇祯皇帝已死老太监就跟着殉葬了. 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束 ...

  4. ABAP-关于 LUW

    转载:https://www.cnblogs.com/liaojunbo/archive/2011/07/12/2103554.html 假设MAIN PROGRAM(调用程序)为MAIN,其所在的为 ...

  5. Datatable数据分组

    datatable里面的数据是按照这个顺序排列的 姓名    性别        年龄 a1          男           12 a1         女             11 a ...

  6. body{font-size: 62.5%;} 解释

    为什么body{font-size: 62.5%;} 2012-10-25 16:15 16778人阅读 评论(0) 收藏 举报  分类: css问题(17)  在网页设计中我们经常看见body{fo ...

  7. Mysql 获取当月和上个月第一天和最后一天的解决方案

    #获取当前日期select curdate(); #获取当月最后一天select last_day(curdate()): #获取本月的第一天select date_add(curdate(),int ...

  8. JAVA 打印流与转换流

    转换流主要有两个 InputStreamReader 和 OutputStreamWriter 1. InputStreamReader 主要是将字节流输入流转换成字符输入流 2. OutputStr ...

  9. Java含有Date的对象序列化网络传输

    与短信接口对接时,Date从我这边传输以及在短信平台接收后转换出了问题 传入一个TemplateRequest对象 Feign接口 将含有Date的将要传输的TemplateRequest加上@Req ...

  10. FIFO 、LRU、LFU三种算法

    提到缓存,有两点是必须要考虑的:(1)缓存数据和目标数据的一致性问题.(2)缓存的过期策略(机制).     其中,缓存的过期策略涉及淘汰算法.常用的淘汰算法有下面几种:(1)FIFO:First I ...