zoukankan      html  css  js  c++  java
  • BZOJ1045

    传送门:BZOJ1045

    结论题。

    ixiave
    aixi+xi1=ave

    i=1n|xi|

    能够构造出
    a1x1+x2=ave
    a2x2+x3=ave
    a1x3+x4=ave
    …..
    anxn+x1=ave

    这个方程组有n个方程和n个变量,但显然。最后一个方程式无意义。


    于是考虑:
    a1x1+x2=avex2=ave+x1a1
    a2x2+x3=avex3=ave+x2a2=2×avea1a2+x1
    a3x3+x4=avex3=3×avea1a2a3+x1

    anxn+x1=ave

    这仅仅要自己计算一下就能够明确,记ci=(ij=1aj)i×ave。于是有
    x2=x1c1
    x3=x1c2
    ……
    i2,xi=x1ci1
    于是最小化的目标函数就是

    |x1|+i=1n1|x1ci|=|x10|+i=1n1|x1ci|

    也就是说,给出数轴上的点(0,c1,c2,c3...cn1)y,y
    y

    完毕推导后做法还是非常优雅的。

    代码上的小细节见下。

    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    int n;
    int a[1000005];
    int c[1000005];
    long long ave;
    
    void Solve()
    {
        for(int i=2;i<=n;i++)
            c[i]=c[i-1]+a[i]-ave;
        sort(c+1,c+n+1);
        long long ans=0;
        int j=(1+n)/2;
        for(int i=1;i<=n;i++)
            ans+=abs(c[j]-c[i]);
        cout<<ans;
    }
    
    void Readdata()
    {
        freopen("loli.in","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            ave+=a[i];
        ave/=n;
    }
    
    void Close()
    {
        fclose(stdin);
        fclose(stdout);
    }
    
    int main()
    {
        Readdata();
        Solve();
        Close();
        return 0;
    }
  • 相关阅读:
    第1关:逆序输出数组元素
    Ubuntu配置java环境安装JDK8
    Ubuntu18安装Tomcat服务
    Windows+ubuntu1803双系统安装
    问题 F: 水仙花数(C#)
    问题 A: C#异或运算符的使用
    hdu 2642 Stars 【二维树状数组】
    poj 2352 stars 【树状数组】
    hdu 1698 Just a Hook 【线段树+lazy】
    线段树【单点更新,区间更新,区间查询,最值查询】
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7072574.html
Copyright © 2011-2022 走看看