【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html
题目描述
输入
输入第一行包含两个整数n,k(k+1≤n)。
输出
输出第一行包含一个整数,为小H可以得到的最大分数。
样例输入
7 3
4 1 3 4 0 2 3
样例输出
108
题解
斜率优化dp
首先可以证得分割的顺序对答案没有影响。
设连续的3部分之和分别为a、b、c,则先分割ab再分割bc的分数为a*(b+c)+b*c=a*b+a*c+b*c,先分割bc再分割ab的分数为(a+b)*c+a*b=a*b+a*c+b*c,它们完全相同。
这样我们就可以从左到右按顺序依次分割。
设f[i][p]表示前i个数分割p次的最大分数,那么有f[i][p]=f[j][p-1]+(sum[i]-sum[j])*sum[j]
这样时间复杂度为O(n^2*p),会TLE,需要优化。
将dp方程变形,得sum[j]*sum[j]-f[j][p-1]=sum[i]*sum[j]-f[i][p],
这样可以斜率优化来解决,此时y=sum[j]*sum[j]-f[j][p-1],k=sum[i],x=sum[j],均为正数(其实是故意这样移项的)。
然后要求的是f[i][p]的最大值,即-f[i][p]的最小值,所以应该维护一个上凸包。
另外需要开long long导致MLE,所以需要滚动数组。
#include <cstdio>
#define y(i , d) (sum[i] * sum[i] - f[i][d])
typedef long long ll;
ll sum[100010] , f[100010][2];
int q[100010];
int main()
{
int n , k , i , j , l , r , d = 0;
scanf("%d%d" , &n , &k);
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &sum[i]) , sum[i] += sum[i - 1];
for(j = 1 ; j <= k ; j ++ )
{
l = r = 0 , d ^= 1;
for(i = 1 ; i <= n ; i ++ )
{
while(l < r && y(q[l + 1] , d ^ 1) - y(q[l] , d ^ 1) <= sum[i] * (sum[q[l + 1]] - sum[q[l]])) l ++ ;
f[i][d] = f[q[l]][d ^ 1] + (sum[i] - sum[q[l]]) * sum[q[l]];
while(l < r && (y(i , d ^ 1) - y(q[r] , d ^ 1)) * (sum[q[r]] - sum[q[r - 1]]) <= (y(q[r] , d ^ 1) - y(q[r - 1] , d ^ 1)) * (sum[i] - sum[q[r]])) r -- ;
q[++r] = i;
}
}
printf("%lld\n" , f[n][k & 1]);
return 0;
}
【bzoj3675】[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]序列分割(斜率优化)
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4186 Solved: 1629[Submit][Status][Discuss] Descript ...
- 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最近迷上了一个分隔序列的游戏. ...
- BZOJ 3675: 序列分割 (斜率优化dp)
Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得到k+1个子序列,小H需要重复k次以下的步骤: 1.小H首 ...
- 2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)
传送门 斜率优化dp经典题目. 首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的. 根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立. 我们设两个断点分成的三段连 ...
随机推荐
- python模块之正则
re模块 可以读懂你写的正则表达式 根据你写的表达式去执行任务 用re去操作正则 正则表达式 使用一些规则来检测一些字符串是否符合个人要求,从一段字符串中找到符合要求的内容.在线测试网站:http:/ ...
- Oracle Like、Instr以及正则表达式
查看测试数据 select * from student; 1. like 在where字句中使用like可以达到模糊查询的效果,常用通配符如下 ▶ %: 使用 % 有三种情况 ① 字段 like ‘ ...
- 利用bootstrap制作滚动监听
滚动监听(Scrollspy)插件,即自动更新导航插件,会根据滚动条的位置自动更新对应的导航目标. 在这里,需要引入三个文件:bootstrap.min.css jquery-3.3.1.j ...
- Centos7下MySql5.7安装及配置
安装MySql 软件包: mysql-community-libs-5.7.22-1.el7.x86_64.rpm mysql-community-common-5.7.22-1.el7.x86_64 ...
- IO流的应用_Copy文件
IO流的应用_Copy文件 (1) import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- 使用c++控制sqlite3
首先,到官网下载相关的压缩包 https://www.sqlite.org/download.html 但是要自己再重新编译一个, 博主自己收集了一下,密码:hixo https://pan.baid ...
- CSS3解决移动端手指点击或滑动屏幕时出现的浅蓝色背景框
当时做完移动端页面发现点击图片(背景图按钮),出现了浅蓝色背景,实属影响页面美观,解决这一问题代码如下 html,body{ -webkit-tap-highlight-color: rgba(0,0 ...
- python__系统 : socket_UDP相关
socket.socket() 可以创建一个套接字: from socket import * from threading import Thread udp_socket = None dest_ ...
- table选项卡
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- MyCat实现数据库与数据库之间的读写分离
一.Mycat的安装准备: 1.jdk:要求jdk必须是1.7及以上版本 2.Mysql:推荐mysql是5.5以上版本 3.Mycat: Mycat的官方网站: http://www.mycat.o ...