问题描述

Pine开始了从S地到T地的征途。

从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。

Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。

Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。

帮助Pine求出最小方差是多少。

设方差是v,可以证明,\(v\times m^2\)是一个整数。为了避免精度误差,输出结果时输出\(v\times m^2\)。

输入格式

第一行两个数 n、m。

第二行 n 个数,表示 n 段路的长度

输出格式

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

样例输入

5 2

1 2 5 8 6

样例输出

36

说明

对于 \(30\%\) 的数据,\(1 \le n \le 10\)。

对于 \(60\%\) 的数据,\(1 \le n \le 100\)。

对于 \(100\%\) 的数据,\(1 \le n \le 3000\)。

保证从 S 到 T 的总路程不超过 30000 。

解析

首先,我们需要化简方差的式子,

\[\begin{align}s^2 &=\frac{\sum_{i=1}^{m}(\overline v-v_i)^2}{m}\\ &=\frac{m\overline v^2-2\overline v(v_1+v_2+...+v_m)+(v_1^2+v_2^2+...+v_m^2)}{m}\\ &=\frac{m\frac{(\sum_{i=1}^{m}v_i)^2}{m^2}-2\frac{(\sum_{i=1}^{m}v_i)^2}{m}+v_1^2+v_2^2+...+v_m^2}{m}\\\end{align}
\]

所以

\[s^2\times m^2=-(\sum_{i=1}^{m}v_i)^2+m(v_1^2+...+v_m^2)
\]

所以,我们需要把路程划分为m个部分,使\(v_1^2+...+v_m^2\)最小。这个可以用动态规划来完成。设\(f[i][j]\)表示将前i个数划分成j段的最小值。我们有如下状态转移方程:

\[f[i][j]=max(f[k][j-1]+(sum[i]-sum[k])^2)
\]

然后这个转移方程可以用斜率优化。

代码

#include <iostream>
#include <cstdio>
#define int long long
#define N 3002
using namespace std;
int n,m,i,j,v[N],sum[N],f[N][N],q[N],head,tail;
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
double k(int x,int i,int j)
{
return 1.0*((f[i][x]+sum[i]*sum[i])-(f[j][x]+sum[j]*sum[j]))/(sum[i]-sum[j]);
}
signed main()
{
n=read();m=read();
for(i=1;i<=n;i++){
v[i]=read();
sum[i]=sum[i-1]+v[i];
f[i][1]=sum[i]*sum[i];
}
for(j=2;j<=m;j++){
head=tail=1;
q[1]=j-1;
for(i=j;i<=n;i++){
while(head<tail&&k(j-1,q[head],q[head+1])<2*sum[i]) head++;
int x=q[head];
f[i][j]=f[x][j-1]+(sum[i]-sum[x])*(sum[i]-sum[x]);
while(head<tail&&k(j-1,q[tail],i)<k(j-1,q[tail],q[tail-1])) tail--;
q[++tail]=i;
}
}
printf("%lld\n",m*f[n][m]-sum[n]*sum[n]);
return 0;
}

[洛谷P4072] SDOI2016 征途的更多相关文章

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

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

  2. 洛谷P4072 [SDOI2016]征途(带权二分,斜率优化)

    洛谷题目传送门 一开始肯定要把题目要求的式子给写出来 我们知道方差的公式\(s^2=\frac{\sum\limits_{i=1}^{m}(x_i-\overline x)^2}{m}\) 题目要乘\ ...

  3. 洛谷P4072 [SDOI2016]征途(斜率优化)

    传送门 推式子(快哭了……)$$s^2*m^2=\sum _{i=1}^m (x_i-\bar{x})^2$$ $$s^2*m^2=m*\sum _{i=1}^m x_i^2-2*sum_n\sum ...

  4. 洛谷4072 SDOI2016征途 (斜率优化+dp)

    首先根据题目中给的要求,推一下方差的柿子. \[v\times m^2 = m\times \sum x^2 - 2 \times sum \times sum +sum*sum \] 所以\(ans ...

  5. 洛谷 P4071 [SDOI2016]排列计数

    洛谷 这是一道组合数学题. 对于一个长为n的序列,首先我们要选m个使之稳定\(C^{m}_{n}\). 且要保证剩下的序列不稳定,即错排\(D_{n-m}\). 所以答案就是:\[ANS=C^{m}_ ...

  6. 【洛谷 P4072】 [SDOI2016]征途(斜率优化)

    好久没写斜率优化板子都忘了, 硬是交了十几遍.. 推一下柿子就能得到答案为 \[m*\sum x^2-(\sum x)^2\] 后面是个定值,前面简单dp,斜率优化一下就行了. \(f[i][j]=f ...

  7. 洛谷 P4070 [SDOI2016]生成魔咒 解题报告

    P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...

  8. 洛谷——P4071 [SDOI2016]排列计数(错排+组合数学)

    P4071 [SDOI2016]排列计数 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列 ...

  9. 洛谷 P4071 [SDOI2016]排列计数 题解

    P4071 [SDOI2016]排列计数 题目描述 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳 ...

随机推荐

  1. C学习笔记-typedef

    typedef是一种高级数据特性,它能使某一类型创建自己的名字 typedef unsigned char BYTE; typedef struct man MAN; BYTE b = 0x12; 与 ...

  2. luoguP1886 滑动窗口(单调队列模板题)

    题目链接:https://www.luogu.org/problem/P1886#submit 题意:给定n个数,求大小为k的滑动窗口中最小值和最大值. 思路:单调队列模板题. AC代码: #incl ...

  3. The Maze

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  4. Java基础(五)

    方法概述 方法的定义格式 什么是方法?方法就好像是一个工厂. 如奶牛场 原料:奶牛,饲料 产出物:牛奶,各种奶制品 程序当中的方法 参数(原料):进入方法的数据 返回值(产出物):从方法中出来的数据 ...

  5. python的学习之路(四)

    #迭代器,取值只能用next方法,不能随意取值name = iter([11,22,33,44])print(name.__next__())print(name.__next__())print(n ...

  6. Docker守护进程

    Docker安装完成之后, 需要确定Docker的守护进程是否已经运行. Docker是使用root 权限运行他的程序,进而可以处理普通用户无法完成的操作(比如挂载文件系统). docker程序是Do ...

  7. 一些通用的js工具类,添加自定义插件

    common_t.js /** * 通用工具组件 对原有的工具进行封装,自定义某方法统一处理<br> * ^_^ * * Author: em.D * Date: 2016-05-17 * ...

  8. 第三章 联接查询 T-SQL语言基础

    联接查询 sql server 2008支持四种表运算符----JOIN,APPLY,PIVOT,UNPIVOT. JOIN表运算符是ANSI标准,而APPLY,PIVOT,UNPIVOT是T-SQL ...

  9. IDEA导入Eclipse 非Maven的Web项目

  10. Swift(一)语言介绍

    Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题. Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其中 ...