题目链接

题目要求使得下面这个式子最小(\(\mu=\frac{\sum_{i=1}^ma_i}{m}\)是平均数,\(a_i\)为第\(i\)段的和): $$\frac{\sum_{i-1}^m(\mu -a_i)2}{m}*m2$$

\(m\)可以乘进去,得: $$m\times\sum_{i=1}m(a_i-\frac{sum}{m})2$$

注意到其中有\(m\)个\(sum\),于是连同乘上的\(m\)一起提出来就是\(m\times\sum_{i=1}^m(a_i^2-2*a_i*\frac{sum}{m})+sum^2\)

\(\sum_{i=1}^m2*a_i\)又是一个\(sum\),于是最终化简为$$m\times\sum_{i=1}ma_i2-sum^2$$

使\(\sum_{i=1}^ma_i^2\)最小,转移方程是\(f[i][j]=f[i-1][k]+(s_j-s_k)^2\)

容易想到有单调性,用斜率优化即可。

\[f_j-f_k+s_j^2-s_k^2\leq 2*s_i*(s_j-s_k)
\]

注意初始化。。即到某点时分一组的值。

下附错误代码(化简不好导致。。)

//868kb	272ms
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=3005; int n,m,sum[N],f[N][2],q[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline int X(int j,int k){
return sum[j]-sum[k];
}
inline int Y(int j,int k,int s){
return f[j][s]-f[k][s]+(sum[j]*sum[j]-sum[k]*sum[k]);
}
inline int Calc_F(int i,int j,int s){
return f[j][s]+(sum[i]-sum[j])*(sum[i]-sum[j]);
} int main()
{
n=read(),m=read();
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+read(),f[i][0]=sum[i]*sum[i];
int p=0;
for(int j=2; j<=m; ++j)
{
int h=1,t=1; q[1]=j-1;//这可以初始化为这个,i从j枚举。
for(int i=j; i<=n; ++i)
{
while(h<t && Y(q[h+1],q[h],p)<=2*sum[i]*X(q[h+1],q[h])) ++h;
f[i][p^1]=Calc_F(i,q[h],p);
while(h<t && 1ll*Y(i,q[t],p)*X(q[t],q[t-1])<=1ll*Y(q[t],q[t-1],p)*X(i,q[t])) --t;
q[++t]=i;
}
p^=1;
}
printf("%d",m*f[n][p]-sum[n]*sum[n]); return 0;
}

错误做法:

题目要求使得下面这个式子最小(\(\mu=\frac{\sum_{i=1}^ma_i}{m}\)是平均数,\(a_i\)为第\(i\)段的和): $$\frac{\sum_{i-1}^m(\mu -a_i)2}{m}*m2$$

\(m\)可以乘进去,得: $$m\times\sum_{i=1}m(\frac{sum}{m}-a_i)2$$

那是个平方,于是写成俩,把\(m\)乘进一个去,得: $$\frac{sum2}{m}-2*a_i*sum+a_i2*m$$

其中 \(a_i=sum_{now}-sum_i\);\(\frac{sum^2}{m}\)是一个常数,直接用。

显然(...)具有决策单调性。然后展开一堆式子,得到。。不写了。

但是不对,暴力也可能和答案差1,因为\(sum^2\)不一定整除\(m\),但那个常数的位置还没法弄掉分母,所以计算\(f[]\)的时候就gg。

怕不是还能用double水

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=3005; int n,m,w,sum[N],f[N],f2[N][N],q[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline int X(int j,int k){
return m*(sum[j]-sum[k]);
}
inline long long Y(int j,int k){
return f[j]-f[k]+2*(sum[j]-sum[k])*sum[n]+(sum[j]*sum[j]-sum[k]*sum[k])*m;
}
inline int Calc_F(int i,int j){
int ai=sum[i]-sum[j];
return f[j]+w-2*ai*sum[n]+ai*ai*m;
} int main()
{
n=read(),m=read();
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+read();
w=sum[n]*sum[n]/m;
memset(f2,0x3f,sizeof f2);
f2[0][0]=1;
for(int i=1; i<=m; ++i)
{
// int h=1,t=1; q[1]=0;
for(int j=i; j<=n; ++j)
{
// while(h<t && Y(q[h+1],q[h])<=2*sum[j]*X(q[h+1],q[h])) ++h;
// f[j]=Calc_F(j,q[h]);
// while(h<t && Y(i,q[t])*X(q[t],q[t-1])<=Y(q[t],q[t-1])*X(i,q[t])) --t;
// q[++t]=j;
for(int k=0; k<j; ++k)
{
int ai=sum[j]-sum[k];
f2[i][j]=std::min(f2[i][j],f2[i-1][k]+w-2*ai*sum[n]+ai*ai*m);
}
}
}
printf("%d",f2[m][n]); return 0;
}

BZOJ.4072.[SDOI2016]征途(DP 斜率优化)的更多相关文章

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

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

  2. BZOJ4518: [Sdoi2016]征途(dp+斜率优化)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1875  Solved: 1045[Submit][Status][Discuss] Descript ...

  3. BZOJ_4518_[Sdoi2016]征途_斜率优化

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

  4. 【BZOJ-4518】征途 DP + 斜率优化

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

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

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

  6. 2018.09.08 bzoj4518: [Sdoi2016]征途(斜率优化dp)

    传送门 把式子展开后发现就是要求: m∗(∑i=1msum′[i])−sum[n]2" role="presentation" style="position: ...

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

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

  8. 洛谷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 ...

  9. BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)

    BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...

随机推荐

  1. Java基础-Java数据类型

    Java基础-Java数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据类型的作用 数据类型就是一组值,以及这一组值上的操作,数据类型可以决定数据的存储方式,取值范围 ...

  2. Struts2_day03

    一.上节回顾 1 在action获取表单提交数据 (1)使用ActionContext类获取 (2)使用ServletActionContext类获取 (3)接口注入 2 结果配置 (1)全局结果页面 ...

  3. NIO学习(1)-入门学习

    一.NIO概念 IO:标准IO,也既阻塞式IO NIO:非阻塞式IO 二.NIO与标准IO的IO工作方式 标准IO基于字节流和字符流进行操作 NIO是基于通道(Channel)和缓冲区(Buffer) ...

  4. Django中合并同一个model的多个QuerySet

    [1]相同modelarticles1 = Article.objects.order_by("autoid").filter(autoid__lt = 16).values('a ...

  5. c++刷题(43/100)矩阵旋转打印

    题目1:矩阵旋转打印 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则 ...

  6. Chrome插件之ModHeader

    一.ModHeader是什么 ModHeader顾名思义就是让我们可以自定义HTTP请求头或者是重写响应头,包括新增请求头/响应头或者覆盖Chrome浏览器设置的请求头的默认值,同时还可以根据URL ...

  7. python3之memcached

    1.memcached介绍 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fi ...

  8. 001_fpm打包命令详解

    使用fpm来制作rpm包 2017/2/22 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ...

  9. 重温CSS之文档结构

    我们来看看几个基本的HTML页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  10. laravel 辅助函数

    数组&对象 1.array_divide() array_divide 函数返回两个数组,一个包含原始数组的健,另一个包含原始数组的值 [$keys, $values] = array_div ...