bzoj 3675: [Apio2014]序列分割【斜率优化dp】
首先看这个得分方式,容易发现就相当于分k段,每段的值和两两乘起来。
这样就很容易列出dp方程:设f[i][j]为到j分成分成i段,转移是
\]
然后显然这个可以斜率优化,随便推一推式子,假设k选p大于选q,那么
\]
\]
\]
\]
维护一个斜率单调的队列即可。
注意s[q]-s[p]可能是0,所以要特判一下
#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
int n,m,to[205][N],q[N];
long long s[N],f[2][N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
inline double wk(int r,int j,int k)
{
if(s[j]==s[k])
return -1e18;
return (f[r&1^1][k]-s[k]*s[k]-f[r&1^1][j]+s[j]*s[j])*1.0/(s[j]-s[k]);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
s[i]=s[i-1]+read();
for(int i=1;i<=m;i++)
{
int l=0,r=0;
for(int j=1;j<=n;j++)
{
while(l<r&&wk(i,q[l],q[l+1])<=s[j])
l++;
to[i][j]=q[l];
f[i&1][j]=f[(i&1)^1][q[l]]+s[q[l]]*(s[j]-s[q[l]]);
while(l<r&&wk(i,q[r-1],q[r])>=wk(i,q[r],j))
r--;
q[++r]=j;
}
}
printf("%lld\n",f[m&1][n]);
for(int i=m,u=n;i>=1;i--)
{
u=to[i][u];
printf("%d ",u);
}
return 0;
}#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
int n,m,to[205][N],q[N];
long long s[N],f[2][N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
inline double wk(int r,int j,int k)
{
if(s[j]==s[k])
return -1e18;
return (f[r&1^1][k]-s[k]*s[k]-f[r&1^1][j]+s[j]*s[j])*1.0/(s[j]-s[k]);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
s[i]=s[i-1]+read();
for(int i=1;i<=m;i++)
{
int l=0,r=0;
for(int j=1;j<=n;j++)
{
while(l<r&&wk(i,q[l],q[l+1])<=s[j])
l++;
to[i][j]=q[l];
f[i&1][j]=f[(i&1)^1][q[l]]+s[q[l]]*(s[j]-s[q[l]]);
while(l<r&&wk(i,q[r-1],q[r])>=wk(i,q[r],j))
r--;
q[++r]=j;
}
}
printf("%lld\n",f[m&1][n]);
for(int i=m,u=n;i>=1;i--)
{
u=to[i][u];
printf("%d ",u);
}
return 0;
}
bzoj 3675: [Apio2014]序列分割【斜率优化dp】的更多相关文章
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
洛谷传送门 题目大意:让你把序列切割k次,每次切割你能获得 这一整块两侧数字和的乘积 的分数,求最大的分数并输出切割方案 神题= = 搞了半天也没有想到切割顺序竟然和答案无关...我太弱了 证明很简单 ...
- BZOJ 3675 APIO2014 序列切割 斜率优化DP
题意:链接 方法:斜率优化DP 解析:这题BZ的数据我也是跪了,特意去网上找到当年的数据后面二十个最大的点都过了.就是过不了BZ. 看到这道题自己第一发DP是这么推得: 设f[i][j]是第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 ...
- 【bzoj3675】[Apio2014]序列分割 斜率优化dp
原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html 题目描述 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列 ...
- BZOJ 3675: [Apio2014]序列分割( dp + 斜率优化 )
WA了一版... 切点确定的话, 顺序是不会影响结果的..所以可以dp dp(i, k) = max(dp(j, k-1) + (sumn - sumi) * (sumi - sumj)) 然后斜率优 ...
- 【斜率DP】BZOJ 3675:[Apio2014]序列分割
3675: [Apio2014]序列分割 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1066 Solved: 427[Submit][Statu ...
- P3648 [APIO2014]序列分割 斜率优化
题解:斜率优化\(DP\) 提交:\(2\)次(特意没开\(long\ long\),然后就死了) 题解: 好的先把自己的式子推了出来: 朴素: 定义\(f[i][j]\)表示前\(i\)个数进行\( ...
- BZOJ 3675 [Apio2014]序列分割 (斜率优化DP)
题目链接 BZOJ 3675 首先最后的答案和分割的顺序是无关的, 那么就可以考虑DP了. 设$f[i][j]$为做了$i$次分割,考虑前$j$个数之后的最优答案. 那么$f[i][j] = max( ...
随机推荐
- BZOJ 2308 莫队入门经典
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2038 参考博客 https://www.cnblogs.com/Paul-Guderi ...
- 一致性哈希算法-----> 解决memecache 服务器扩容后的数据丢失。
1 基本场景 比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 ...
- POJ 3013 【需要一点点思维...】【乘法分配率】
题意: (这题明显感觉自己是英语渣) 给n个点从1到n标号,下面一行是每个点的权,另外给出m条边,下面是每条边的信息,两个端点+权值,边是无向边.你的任务是选出一些边,使这个图变成一棵树.这棵树的花费 ...
- POJ 1511 【heap+dij】
题意: t组样例. 每组有n个节点,有m条单向边. 有m组输入,每组a b c 表示从a到b的单向边的权值是c. 求解,从编号为1的节点出发,有n-1个人,要求他们分别到达编号从2到n的节点再返回,所 ...
- HDU 1558
输入线段的两个短点,如果线段相交那么他们属于一个集合,查看第i条线段所在的集合有几条线段. 好久没码码了,总是各种蠢. 首先找出两条直线的方程,求解相交点的横坐标,然后看是不是在线段内部. 没有注意题 ...
- Meteor核心API
在本教程中,我们将介绍学习Meteor核心API. 如果你想限制代码只在服务器或客户端可以使用下面的代码运行 - meteorApp.js if (Meteor.isClient) { // Code ...
- hdu 5303 Delicious Apples
这道题贪心 背包 假设在走半圆之内能够装满,那么一定优于绕一圈回到起点.所以我们从中点将这个分开,那么对于每一个区间由于苹果数非常少,所以能够利用pos[x]数组记录每一个苹果所在的苹果树位置,然后将 ...
- MySQL的引入,绿色包下载和应用
一.下载MySQL绿色版 1.下载地址: 以下是MySQL最新绿色版链接(都是来源于oracle官网),点击以下链接直接下载. 1.1.官网链接:https://www.oracle.com/inde ...
- c++学习笔记之基础---类内声明线程函数的调用
近日需要将线程池封装成C++类,类名为Threadpool.在类的成员函数exec_task中调用pthread_create去启动线程执行例程thread_rounter.编译之后报错如下: spf ...
- HDU 4277 USACO ORZ(暴力+双向枚举)
USACO ORZ Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...