题目描述

给定长为 n 的数列 a, 要求划分成 m 段,使得方差最小, 输出方差\(*m^2\)

题解

斜率优化好题

准备部分

设第 i 段长为 \(len_i\)

先考虑方差(\(S^2\))的式子:

\[S^2 = \frac{1}{m}*\sum_{i=1}^m(len_i - (\frac{1}{m}*\sum_{j=1}^{m}len_j) )^2
\]

拆项得 -->

\[S^2 = \frac{1}{m}\sum_{i=1}^{m}len_i^2+\frac{1}{m}\sum_{i=1}^{m}\frac{1}{m^2}\sum_{j=1}^{m}len_j-2*\frac{1}{m}*\sum_{i=1}^{m}(len[i]*\frac{1}{m}\sum_{j=1}^{m}len_j)
\]

-->

\[S^2 = \frac{1}{m}\sum_{i=1}^{m}len_i^2+\frac{1}{m^2}\sum_{i=1}^{m}len_i^2-2*\frac{1}{m^2}*(\sum_{i=1}^{m}len_i)*(\sum_{j=1}^{m}len_j)
\]

-->

\[S^2 = \frac{1}{m}\sum_{i=1}^{m}len_i^2-\frac{1}{m^2}\sum_{i=1}^{m}len_i^2
\]

再把\(m^2\)乘进去

\[m*\sum_{i=1}^{m}len_i^2-\sum_{i=1}^{m}len_i^2
\]

可发现$$-\sum_{i=1}^{m}len_i^2$$ 这一坨是常数,也就是原序列和的平方

然后开始DP

设 f[i][k] 表示当前在第 i 个数,划分成 k 段

转移时枚举第 k 段的起点 j+1 (终点是 i ,注意这里枚举的是j+1):

\[f[i][k] =f[j][k-1]+(\sum_{l=j+1}^{i}a[l])^2
\]

再用滚动数组g(也可不用)与前缀和sum记录一下 a[l] 优化就好

也就是

\[f[i]=g[j]+(sum[i]-sum[j])^2
\]

斜率优化

把上面的DP转移方程拆开即得:

\[g[j]+sum[j]^2=-2*sum[i]*sum[j]+(sum[i]^2-f[i])
\]

把\(g[j]+sum[j]^2\) 看做 Y;

把\(sum[j]^2\) 看做 X;

把\(-2*sum[i]\) 看做 K;

把\((sum[i]^2-f[i])\) 看做 B;

然后用单调队列维护一下斜率递增的决策点就好

代码

#include<bits/stdc++.h>
using namespace std;
#define re register
#define in inline
#define get getchar()
#define ll long long
in int read()
{
int t=0; char ch=get;
while(ch<'0' || ch>'9') ch=get;
while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
return t;
}
const int _=5001;
int n,m;
ll sum[_],f[_],g[_],q[_];
#define db double
in db calc(int a,int b)
{
ll Y1=g[a]+sum[a]*sum[a],Y2=g[b]+sum[b]*sum[b];
return 1.0*(Y1-Y2)/(sum[a]-sum[b]);
}
int main()
{
n=read(),m=read();
for(re int i=1;i<=n;i++){
sum[i]=sum[i-1]+read();
g[i]=sum[i]*sum[i];
}
for(re int k=2;k<=m;k++)
{
int l=1,r=0;
q[l]=0;q[0]=0;
for(re int i=1;i<=n;i++)
{
while(l<r && calc(q[l],q[l+1]) < 2*sum[i]) l++;
int j=q[l];
f[i]=g[j]+(sum[i]-sum[j])*(sum[i]-sum[j]);
while(l<r && calc(q[r],i) < calc(q[r-1],i)) r--;
q[++r]=i;
}
memcpy(g,f,sizeof(g));
}
cout<<m*f[n]-sum[n]*sum[n]<<endl;
}

SDOI征途--斜率优化的更多相关文章

  1. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

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

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

  3. BZOJ 4518: [Sdoi2016]征途 [斜率优化DP]

    4518: [Sdoi2016]征途 题意:\(n\le 3000\)个数分成m组,一组的和为一个数,求最小方差\(*m^2\) DP方程随便写\(f[i][j]=min\{f[k][j-1]+(s[ ...

  4. bzoj4518[Sdoi2016]征途 斜率优化dp

    4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1657  Solved: 915[Submit][Status] ...

  5. [SDOI2016 Round1] 征途[斜率优化]

    2225. [SDOI2016 Round1] 征途 ★★★☆   输入文件:menci_journey.in   输出文件:menci_journey.out   简单对比时间限制:1 s   内存 ...

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

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

  7. 【bzoj4518】[Sdoi2016]征途 斜率优化dp

    原文地址:http://www.cnblogs.com/GXZlegend/p/6812435.html 题目描述 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界 ...

  8. [bzoj4518][Sdoi2016]征途-斜率优化

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

  9. bzoj4518征途 斜率优化

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

随机推荐

  1. org.springframework.beans.factory.BeanCurrentlyInCreationException

    昨天下午的时候,给公司的项目打了个版,发现一直报502错误了,最后在服务器日志上看了一下异常信息,发现报了以下异常信息,导致项目启动就报错了(pc:该项目在我电脑本地启动不报错,之前也没报错). 错误 ...

  2. 原生JavaScript封装的jsonp跨域请求

    原生JavaScript封装的jsonp跨域请求 <!DOCTYPE html> <html lang="en"> <head> <met ...

  3. eureka集群的搭建

    本次将会创建三个注册中心和一个客户端进行集群,架构图如下: 修改本机hosts文件,创建三个域名: 代码结构如图: 由于三个注册中心结构都是一样的,区别在于配置文件: #注册中心(eureka-ser ...

  4. 概率派VS贝叶斯派

    机器学习中的MLE和MAP两大学派的争论: 频率学派 - Frequentist - Maximum Likelihood Estimation (MLE,最大似然估计): 频率学派认为世界是确定的, ...

  5. 0921 LCA练习

    1.poj 1330 数据结构中的树,在计算机科学中是非常重要的,例如我们来看看下面这棵树: 在图中我们对每个节点都有编号了. 8号节点是这棵树的根.我们定义,一个子节点向它的根节点的路径上,任意一个 ...

  6. Anaconda安装Pytorch(通过本地安装包)

    前提:你已经事先安装好了Anaconda 在线安装pytorch总是出现这样那样的问题,所以我选择先去清华镜像下载好与python版本对应的pytorch和torchvision文件,然后本地安装 清 ...

  7. Java知识系统回顾整理01基础01第一个程序04创建Eclipse项目

    一.为Eclipse设置桌面快捷方式图标 二.双击桌面快捷方式打开Eclipse 三.选择工作区 使用在命令行Hello World中的项目目录e:\project 除了第一次启动eclipse的时候 ...

  8. 05 C语言的数据类型

    C语言的数据类型 在C 中,数据类型是用来声明不同类型的变量或函数的一个广泛的概念.变量的数据类型决定了变量存储占用的空间大小,以及如何去解释存储的位模式. C 中的数据类型可分为以下几大类: 序号 ...

  9. 利用Python求解二元一次方程

    本程序流程如下: (1)输入A.B.C (2)计算△ (3)判断解的个数 (4)计算解 (5)输出解 求:x2-3x+2=0的解 #输入A.B.C A=float(input("输入A:&q ...

  10. Python--网络爬虫模块requests模块之响应--response

    当requests发送请求成功后,requests就会得到返回值,如果服务器响应正常,就会接收到响应数据: Response响应中的属性和方法 常用属性: status_code: 数据类型:int ...