传送门

没想到这种多个状态转移的还能用上斜率优化……学到了……

首先我们可以发现,切的顺序对最终答案是没有影响的

比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得分是$ab+bc+ac$,而如果先切$bc$再切$ab$,得分也是$ab+bc+ac$,不难看出得分是一样的

那么我们可以考虑一下转移方程$$dp[a][i]=max\{dp[a-1][j]+sum[j]*(sum[i]-sum[j])\}$$

其中$a$表示切几刀,$sum$表示前缀和

然后发现空间复杂度太大了,又发现每一刀的状态只与前一刀有关,那么可以用滚动数组优化

然后上面的转移是$O(n^2k)$的,那么考虑用斜率优化优化到$O(nk)$(以下省略dp的第一维)

我们假设$j>k$且$j$比$k$更优,则有$$dp[j]+sum[j]*(sum[i]-sum[j])>dp[k]+sum[k]*(sum[i]-sum[k])$$

$$(dp[j]-sum[j]^2)-(dp[k]-sum[k]^2)>sum[i]*sum[k]-sum[i]*sum[j]$$

因为$sum[k]-sum[j]$是负数,所以除的时候不等式要变号

$$\frac{(dp[j]-sum[j]^2)-(dp[k]-sum[k]^2)}{sum[k]-sum[j]}<sum[i]$$

然后直接上斜率优化

注意特判$sum[k]-sum[j]=0$,随便返回极大值或极小值

顺便注意记录路径

 //minamoto
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
const int N=;
int to[][N],q[N],n,k,h,t,r;
ll sum[N],dp[][N];
inline double slope(int j,int k){
if(sum[j]==sum[k]) return 1e18;
return ((dp[r^][j]-sum[j]*sum[j])-(dp[r^][k]-sum[k]*sum[k]))*1.0/(sum[k]-sum[j]);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),k=read();
for(int i=;i<=n;++i) sum[i]=read()+sum[i-];
for(int a=;a<=k;++a){
r=a&;
h=t=;
for(int i=;i<=n;++i){
while(h<t&&slope(q[h],q[h+])<sum[i]) ++h;
to[a][i]=q[h];
dp[r][i]=dp[r^][q[h]]+sum[q[h]]*(sum[i]-sum[q[h]]);
while(h<t&&slope(q[t],q[t-])>slope(q[t-],i)) --t;q[++t]=i;
}
}
printf("%lld\n",dp[k&][n]);
for(int i=k,u=n;i;--i){
u=to[i][u];
print(u);
}
Ot();
return ;
}

洛谷P3648 [APIO2014]序列分割(斜率优化)的更多相关文章

  1. 洛谷 P3648 [APIO2014]序列分割 解题报告

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

  2. 洛谷 P3648 [APIO2014]序列分割

    题意简述 有一个长度为n的序列,分成k + 1非空的块, 选择两个相邻元素把这个块从中间分开,得到两个非空的块. 每次操作后你将获得那两个新产生的块的元素和的乘积的分数.求总得分最大值. 题解思路 f ...

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

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

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

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

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

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

  6. 洛谷3648 [APIO2014]序列分割(斜率优化+dp)

    首先对于这个题目. qwq 存在一个性质就是,最终的答案只跟你的分割的位置有关,而和顺序无关. 举一个小栗子 \(a\ b\ c\) 将这个东西分成两块. 如果我们先分割\(ab\)之间的话,\(an ...

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

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

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

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

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

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

随机推荐

  1. AngularJS:SQL

    ylbtech-AngularJS:SQL 1.返回顶部 1. AngularJS SQL 在前面章节中的代码也可以用于读取数据库中的数据. 使用 PHP 从 MySQL 中获取数据 AngularJ ...

  2. 转:MongoDB · 引擎特性 · journal 与 oplog,究竟谁先写入?

    转:MongoDB · 引擎特性 · journal 与 oplog,究竟谁先写入? 数据库内核月报 链接:http://mysql.taobao.org/monthly/2018/05/07/ Mo ...

  3. 第六章 Java并发容器和框架

    ConcurrentHashMap的实现原理与使用 ConcurrentHashMap是线程安全且高效的hashmap.本节让我们一起研究一下该容器是如何在保证线程安全的同时又能保证高效的操作. 为什 ...

  4. CALayer绘图

    一.CALayer绘图方式 Layer绘图有两种方法,不管使用哪种方法绘制完必须调用图层的setNeedDisplay方法(注意是图层的方法,不是UIView的方法,UIView的setNeedDis ...

  5. Android APP使用系统签名

    Android M平台在写APP测试使用MediaRecoder通过AudioSource.VOICE_CALL来录制通话上下行音的时候,需要权限 <uses-permission androi ...

  6. java,js判断全角半角

    function chkHalf(str){ for(var i=0;i { strCode=str.charCodeAt(i); if((strCode>65248)||(strCode==1 ...

  7. MS_SQL_获取字符串最后出现的字符串及位置

      一.如:'6.7.8.2.3.4.x'得到最后一个'.'后面的字符串: declare @str1 varchar(50) set @str1='6.7.8.2.3.4.x' select REV ...

  8. nodejs读文件

    1.异步读取文件:var fs= require('fs'); // 从文件系统中读取请求的文件内容 fs.readFile(pathname.substr(1), function (err, da ...

  9. String/StringBuilder 类 统计字符串中字符出现的次数

    1.1. 训练描述:[方法.String类] 一.需求说明:定义如下字符串: String str = “javajfiewjavajfiowfjavagkljjava”; 二.请分别定义方法统计出: ...

  10. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...