4518: [Sdoi2016]征途

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

Pine开始了从S地到T地的征途。
从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。
Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。
Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。
帮助Pine求出最小方差是多少。
设方差是v,可以证明,v×m^2是一个整数。为了避免精度误差,输出结果时输出v×m^2。

Input

第一行两个数 n、m。
第二行 n 个数,表示 n 段路的长度

Output

一个数,最小方差乘以 m^2 后的值

Sample Input

5 2
1 2 5 8 6

Sample Output

36

HINT

1≤n≤3000,保证从 S 到 T 的总路程不超过 30000

题解:

推式子的感觉真刺激呀....

我们复习一下方差的定义:数值与平均值之差的平方和的平均值

设s[i]为前缀和,设X0是平均值,则X0=s[n]/m

也就是说,V=((X1-X0)2+(X2-X0)2+......+(Xm-X0)2)/m

由于答案是V*m2,所以我们不妨把m2直接带上.

所以有:

ans=((X1-X0)2+(X2-X0)2+......+(Xm-X0)2)*m

   =m*ΣXi2+m*X02*m-2*X0*m*ΣXi

   =m*ΣXi2+s[n]2-2*s[n]2

=m*ΣXi2-s[n]2

这样我们就找到了一个很简洁的表达式

但是如果直接计算这个式子,你会发现推不出来,所以我们转化一下角度,转而计算ΣXi2的值.

我们可以维护一个数组f[i][j],表示在第j段路结尾,第i次休息的时候最小的ΣXi2,那么答案就是m*f[m][n]-s[n]2

那么f[i][j]=min{f[k][j-1]+(s[i]-s[k])2}.

分析一下复杂度,Ο(m*n*n),如果是极限数据会变成30003,这样就要t了

所以我们考虑优化,对于可能转移到i的2个位置k1与k2,k1优于k2的条件是什么?(公式恐惧症的同学不要跑啊......)

f[k1][j-1]+(s[i]-s[k1])2<f[k2][j-1]+(s[i]-s[k2])2

f[k1][j-1]-f[k2][j-1]<(s[i]-s[k2])2-(s[i]-s[k1])2

f[k1][j-1]-f[k2][j-1]<s[i]2-2*s[i]*s[k2]+s[k2]2-(s[i]2-2*s[i]*s[k1]+s[k1]2)

f[k1][j-1]-f[k2][j-1]<s[k2]2-s[k1]2-2*s[i]*s[k2]+2*s[i]*s[k1]

f[k1][j-1]-f[k2][j-1]+s[k1]2-s[k2]2<2*s[i]*(s[k1]-s[k2])

(f[k1][j-1]-f[k2][j-1]+s[k1]2-s[k2]2)/(s[k1]-s[k2])<2*s[i]

所以我们用一个单调队列维护就行啦,剩下的维护判断就比较简单了~

代码见下:

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=;
LL len[N],n,m,s[N],f[N][N];
int q[N];
inline int min(int a,int b){return a<b?a:b;}
inline double k(int j,int k1,int k2)
{
double a=(double)(f[j-][k1]-f[j-][k2]+s[k1]*s[k1]-s[k2]*s[k2]);
return a/(double)(s[k1]-s[k2]);
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
scanf("%lld",&len[i]),s[i]=s[i-]+len[i];
for(int j=;j<=n;j++)
f[][j]=s[j]*s[j];
for(int i=,h=,t=;i<=m;i++,h=,t=)
{
memset(q,,sizeof(q));
for(int j=;j<=n;j++)
{
while(h<t&&k(i,q[h+],q[h])<*s[j])h++;
f[i][j]=f[i-][q[h]]+(s[j]-s[q[h]])*(s[j]-s[q[h]]);
while(h<t&&k(i,j,q[t])<k(i,q[t],q[t-]))t--;
q[++t]=j;
}
}
printf("%lld",m*f[m][n]-s[n]*s[n]);
}

BZOJ4815

[BZOJ4518]征途的更多相关文章

  1. bzoj4518征途 斜率优化

    征途这是一道十分经典的斜率优化 我们可以从题目中的方差来想,也就很容易的到这个式子 \[ans=m^2*\frac{\sum_{i=1}^{m}{(x_i-{\overline{x}})^2}}{m} ...

  2. P4072 [SDOI2016](BZOJ4518) 征途 [斜率优化DP]

    题目描述 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路 ...

  3. [SDOI2015][bzoj4518] 征途 [斜率优化dp]

    题面 传送门 思路 把$vm^2$展开化一下式子,可以得到这样的等价公式: $vm^2=m\sum_{i=1}^m a_i^2-\sum_{i=1}^m a_i$ 那么我们要最小化的就是$\sum_{ ...

  4. [SDOI2016]部分题选做

    听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...

  5. SDOI2016 Round1 题解

    BZOJ4513 储能表 数位DP,f[i][2][2][2]表示前i位,是否卡n的上界,是否卡m的上界,是否卡k的下界,枚举每一维的下一位直接转移. #include<cstdio> # ...

  6. 【BZOJ4518】[Sdoi2016]征途 斜率优化

    [BZOJ4518][Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除 ...

  7. BZOJ4518 Sdoi2016 征途 【斜率优化DP】 *

    BZOJ4518 Sdoi2016 征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m ...

  8. 【bzoj4518】 Sdoi2016—征途

    http://www.lydsy.com/JudgeOnline/problem.php?id=4518 (题目链接) 题意 给出n个连续的整数,求将它们分成m段,求最小方差*m^2. Solutio ...

  9. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

随机推荐

  1. checkbox的选中、全选、返选、获取所有选中的值、所有的值、单选全部时父选中

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  2. linux下编译安装nginx

    1.首先下载稳定版nginx1.10.2 使用wget命令下载 wget http://nginx.org/download/nginx-1.10.2.tar.gz 2.然后解压 tar -zxvf  ...

  3. webpack学习(三)之web-dev-server不能自动刷新问题

    使用webpack-dev-server中遇到不能浏览器无法自动刷新的问题:寻找多方答案后明白了一些: 下面有一些需要注意的点: 1.webpack-dev-server并不能读取你的webpack. ...

  4. Github--账号重新申请与配置

    2017-04-24 最近洗心革面痛下决心要好好再深入学习一番前端,正好加入了一个外包团队接了份单子,外包项目正在如火如荼地进行着,自己也打算趁这个机会来好好学习总结一番. 但是俗话说得好," ...

  5. Play初识

    2015年11月21日,写下这篇<Play初识> Play是神马呢?不是Google Play,而是一个java的web框架,因为它抛弃了传统的servlet模式的做法,国内网络连接pla ...

  6. 多源最短路Floyd 算法————matlab实现

    弗洛伊德(Floyd)算法是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想 通过Floyd计 ...

  7. 大数据和BI商业智能有何区别?有何相关?

    大数据 ≠BI商业智能,大数据也不是传统商业智能的简单升级. 1.大数据和BI两者的区别 BI(BusinessIntelligence)即商业智能,它是企业数据化管理的一整套的方案,用来将企业中现有 ...

  8. 属于自己的MES(一)概念

    什么叫MES(生产制造执行系统)? 从几个方面来简单说下: 1.定位 没有MES前的工厂生产模式,公司MRP系统与生产现场之间透过人为方式沟通,使生产现场如同黑箱作业,无法掌握实时正确信息. MES的 ...

  9. redis集群安装部署

    (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下) 192.168.1.160:7000 192. ...

  10. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...