• bzoj4518


    好久没写题解了……

    一开始脑抽,还以为平均数会随着划分的改变而改变(无可救药……)

    这题还是比较水的,展开方差的式子分成m部分每部分路程为xi,平均数p

    方差=∑(xi-p)/m=∑(xi^2-2xi*p+p^2)/m=∑xi^2/m-2*S*p/m+p^2=∑xi^2/m-p^2

    所以只要求∑xi^2即可,不难想到f[i,j]=min(f[k,j-1]+sqr(s[i]-s[k])

    裸的斜率优化即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<stdlib.h>
     6 
     7 using namespace std;
     8 int s[3010],g[3010],f[3010],q[3010];
     9 int n,m;
    10 
    11 int sqr(int x)
    12 {
    13     return x*x;
    14 }
    15 double k(int j,int k)
    16 {
    17        return (sqr(s[k])-sqr(s[j])+g[k]-g[j])/(s[k]-s[j]);
    18 }
    19 
    20 int main()
    21 {
    22     scanf("%d%d",&n,&m);
    23     for (int i=1; i<=n; i++) 
    24     {
    25         scanf("%d",&s[i]);
    26         s[i]+=s[i-1];
    27         g[i]=sqr(s[i]);
    28     }
    29     for (int j=1; j<m; j++)
    30     {
    31         int h=1,r=1; q[1]=j;
    32         for (int i=j+1; i<=n; i++)
    33         {
    34             while (h<r&&k(q[h],q[h+1])<2*s[i]) h++;
    35             f[i]=g[q[h]]+sqr(s[i]-s[q[h]]);
    36             while (h<r&&k(q[r-1],q[r])>k(q[r],i)) r--;
    37             q[++r]=i;
    38         }         
    39         memcpy(g,f,sizeof(g));
    40         memset(f,0,sizeof(0));
    41     }
    42     printf("%d",m*f[n]-sqr(s[n]));
    43     return 0;
    44 }
    45 
    46         
    View Code
  • 相关阅读:
    1005: [HNOI2008]明明的烦恼
    1006: [HNOI2008]神奇的国度
    1007: [HNOI2008]水平可见直线
    1011: [HNOI2008]遥远的行星
    1025: [SCOI2009]游戏
    HTTP1.0和HTTP1.1的区别
    各排序算法的时间复杂度和空间复杂度
    换钱最少货币数
    矩阵的最小路径和
    背包问题
  • 原文地址:https://www.cnblogs.com/phile/p/5645054.html
Copyright © 2020-2023  润新知