【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)
题目链接
假设有\(3\)段\(a,b,c\)
先切\(ab\)和先切\(bc\)的价值分别为
\(a(b+c)+bc=ab+bc+ac\)
\((a+b)c+ab=ab+bc+ac\)
归纳一下可以发现切的顺序并不影响总价值。
于是设\(f[i][j]\)表示前\(i\)个数切\(j\)次的最大价值,转移方程就很简单了。
然后斜率优化一下就能降时间复杂度降到\(O(nk)\)
\(f[i][j]=f[k][j-1]+sum[k]*(sum[i]-sum[k])\)
\(f[k][j-1]-sum[k]^2=-sum[i]*sum[k]+f[i][j]\)
水分神器斜率优化
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100010;
const int MAXM = 205;
#define ll long long
#define re register
int n, m, p;
int q[MAXN], head, tail, sum[MAXN], fa[MAXN][MAXM];
ll f[MAXN][MAXM];
inline double k(int t, int i, int j){
if(sum[i] == sum[j]) return -2e18;
return (double)(f[i][t] - f[j][t] - (ll)sum[i] * sum[i] + (ll)sum[j] * sum[j]) / (sum[i] - sum[j]);
}
int main(){
scanf("%d%d", &n, &m);
for(re int i = 1; i <= n; ++i){
scanf("%d", &p);
sum[i] = sum[i - 1] + p;
}
for(re int j = 1; j <= m; ++j){
head = tail = 0;
for(re int i = 1; i <= n; ++i){
while(head < tail && k(j - 1, q[head], q[head + 1]) > -sum[i]) ++head;
re int l = q[head];
f[i][j] = f[l][j - 1] + (ll)sum[l] * (sum[i] - sum[l]);
fa[i][j] = l;
while(head < tail && k(j - 1, q[tail - 1], q[tail]) <= k(j - 1, q[tail], i)) --tail;
q[++tail] = i;
}
}
printf("%lld\n", f[n][m]);
int now = fa[n][m];
while(m--){
printf("%d ", now);
now = fa[now][m];
}
return 0;
}
【洛谷 P3648】 [APIO2014]序列分割 (斜率优化)的更多相关文章
- 洛谷 P3648 [APIO2014]序列分割 解题报告
P3648 [APIO2014]序列分割 题目描述 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的 ...
- 洛谷P3648 [APIO2014]序列分割(斜率优化)
传送门 没想到这种多个状态转移的还能用上斜率优化……学到了…… 首先我们可以发现,切的顺序对最终答案是没有影响的 比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得 ...
- 洛谷 P3648 [APIO2014]序列分割
题意简述 有一个长度为n的序列,分成k + 1非空的块, 选择两个相邻元素把这个块从中间分开,得到两个非空的块. 每次操作后你将获得那两个新产生的块的元素和的乘积的分数.求总得分最大值. 题解思路 f ...
- P3648 [APIO2014]序列分割 斜率优化
题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...
- 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 ...
- 洛谷3648 [APIO2014]序列分割(斜率优化+dp)
首先对于这个题目. qwq 存在一个性质就是,最终的答案只跟你的分割的位置有关,而和顺序无关. 举一个小栗子 \(a\ b\ c\) 将这个东西分成两块. 如果我们先分割\(ab\)之间的话,\(an ...
- BZOJ3675: [Apio2014]序列分割(斜率优化)
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4186 Solved: 1629[Submit][Status][Discuss] Descript ...
- 【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
随机推荐
- 安装libvirt管理套件(C/S架构模式,用户管理kvm虚拟机)
# 1:安装程序包 yum install -y libvirt virt-manager virt-viewer virt-install qemu-kvm # 2:启动libvirtd守护进程 ...
- WordPress使用淘宝IP地址库的API显示评论者的位置信息(二)
1 淘宝IP地址库的接口说明 在上一篇文章<WordPress使用淘宝IP地址库的API显示评论者的位置信息(一)>中,vfhky使用了新浪工具提供的这个IP接口显示博客评论者的位置信息. ...
- PHP之implode()方法
implode — 将一个一维数组的值转化为字符串 string implode ( string $glue , array $pieces ) string implode ( array $pi ...
- C# 为VB6.0程序模拟串口数据
为VB6.0编写程序模拟数据测试使用. 一.VB6.0 控件MSComm,来发送接收串口数据 CommPort 属性设置并返回通讯端口号,虚拟端口为COM2. Settings 属性设置并返回端口的波 ...
- Appium与Robotium区别
Appium是基于UIAutomator框架实现的.Appium测试进程与目标应用进程是分开的,所以Appium不能直接访问目标应用的各种element属性进行copy&paste,而只能模拟 ...
- 基于jwt的token验证
一.什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该token被设计为紧凑且安全的,特别适用于分布 ...
- [BZOJ3223]文艺平衡树 无旋Treap
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个 ...
- 【PDF】HTML中嵌入pdf的简单方法
<embed src="> 或者你不想显示某些功能的话: <embed src=">
- Linux必知必会——od命令
1.功能 od命令用于将指定文件内容以八进制.十进制.十六进制.浮点格式或ASCII编码字符方式显示,通常用于显示或查看文件中不能直接显示在终端的字符.od命令系统默认的显示方式是八进制,名称源于Oc ...
- 手脱ASPack v2.12
1.PEID查壳提示为: ASPack 2.12 -> Alexey Solodovnikov 2.载入OD,程序入口点是一个pushad,在他的下一行就可以进行ESP定律,下硬件访问断点然后s ...