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. 将子域名请求路由到MVC区域

    写了个扩展,分享给需要的朋友. 0x01 使用方法 在mvc区域中的{xxxx}AreaRegistration.cs文件中,如ProjectsAreaRegistration.cs <pre& ...

  2. shopping_cart

    #!/usr/bin/env python # -*- coding: utf-8 -*- print('欢迎土豪光临随心所欲旗舰店') user_money = int(input('老板,请输入你 ...

  3. 基于django做HTTP代理服务器

    计算机网络的一次小实验,最后一共用了不到100行 实现了: a) 网站过滤:允许/不允许访问某些网站: b) 用户过滤:支持/不支持某些用户访问外部网站: c) 网站引导:将用户对某个网站的访问引导至 ...

  4. 关于vector push_back()与其他方式读取数据的效率对比

    引言: 在读取大量数据(数组)时,使用vector会尽量保证不会炸空间(MLE),但是相比于scanf的读取方式会慢上不少.但到底效率相差有多大,我们将通过对比测试得到结果. 测试数据:利用srand ...

  5. 576. Out of Boundary Paths

    Problem statement: There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball ...

  6. Ajax与Pjax请求在服务端是如何识别的

    我在后台处理ajax和一般的网页请求时,一般是需要额外加个参数进行区分的.比如使用get参数的is_ajax=1,后台判断有is_ajax=1成立时,表明该请求是ajax请求,遂可区分处理.我正在使用 ...

  7. Linux文件查看与查找命令

    cat  查看一个文件 -E: 显示行结束符$ -n: 对显示出的每一行进行编号 -A:显示所有控制符 -b:非空行编号 -s:压缩连续的空行成一行 -T:显示制表符 常用:cat -An /etc/ ...

  8. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  9. 用cv::Scalar来设置opencv中图片的颜色

    1 怎样使用cv::Scalar来设置opencv中的颜色 cv::Scalar的构造函数是cv::Scalar(v1, v2, v3, v4),前面的三个参数是依次设置BGR的,和RGB相反,第四个 ...

  10. C#访问ORALCE数据库

    随着时间的推移知识也在更新,原来可用的技术也会被淘汰或更新. framework4.0开始不再支持System.Data.OracleClient了,但是令人欣慰的是ORACLE公司自己出了一个Ora ...