zoukankan      html  css  js  c++  java
  • UVA.11300 Spreading the Wealth (思维题 中位数模型)

    UVA.11300 Spreading the Wealth (思维题)

    题意分析

    现给出n个人,每个人手中有a[i]个数的金币,每个人能给其左右相邻的人金币,现在要求你安排传递金币的方案,使得每个人手中的金币个数相等,并求出转移金币的最小个数。保证(Σa[i])/n为整数。

    第一眼没有思绪,这种推导方式还是第一次见到。
    设ai为第i个人初始金币数量,xi为第i个人转移给i-1个人金币的数量(i为1表示转移给第n个人),(Σa[i])/n = m。

    有了上述的基础,可以写出每个人的金币表达式:
    即每个人最终的金币数量 = 他的初始化数量-转移走的数量+转移来的数量
    a1 - x1 + x2 = m
    a2 - x2 + x3 = m
    a3 - x3 + x4 = m
    ……
    an - xn + x1 = m

    可以写出n个式子,但是这n个式子中只有n-1个有用,因为任意一个式子都可以由剩下的n-1个式子推出。读者可以一试:将1至n-1个式子叠加,可以得到第n个式子。

    于是我们要想办法利用这n-1个式子,关键就是:转换成单变量。
    我们此处都转换成以x1为变量的式子,即用x1表示xi(i≠1):

    x2 = m-a1+x1
    x3 = m-a2+x2 = m-a2+m-a1+x1 = 2m-a2-a1+x1
    x4 = m-a3+x3 = m-a3+2m-a2-a1+x1 = 3m-a3-a2-a1+x1
    ……
    xn = (n-1)m - Σai( 1<=i<=(n-1) ) + x1

    再由于n,m,ai均为常数,上述xi的表达式变量均为x1,但是这样依旧不够,仍旧需要转化成中位数模型

    先抛开原题,考虑这样一个问题:
    数轴上有n个点,现在求到这n个点的距离和最小的点在哪里。答案就是这些点坐标的中位数。证明笔者就不给出了,可以参考大白书,有兴趣的读者可以一试。

    回到原题,我们将xi的表达式改写:
    x1 = x1 - 0
    x2 = x1 -(a1-m)
    x3 = x1 -(a2+a1-2m)
    x4 = x1 -(a3+a2+a1-3m)
    ……

    别忘了我们xi表达的是金币转移的数量,即为正数,故所求需要加绝对值,那么 :
    |x1| = |x1 - 0|
    |x2| = |x1 -(a1-m)|
    |x3| = |x1 -(a2+a1-2m)|
    |x4| = |x1 -(a3+a2+a1-3m)|
    这么一写,是不是就是上面说的中位数的模型了,其中0,(a1-m),(a2+a1-2m),(a3+a2+a1-3m)……不妨看成是数轴上一系列的点。x1即为需要求出的中位数。 求出中位数后,带入上式累加,即可求出最终的答案。

    代码总览

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define nmax 1000005
    #define ll long long
    using namespace std;
    ll a[nmax],c[nmax];
    int main()
    {
        int n;
        while(scanf("%d",&n) != EOF){
            ll sum = 0;
            for(int i = 0; i<n; ++i){scanf("%d",&a[i]);sum+=a[i];}
            ll t = sum/n;c[0] = 0;
            //ci 为对应的0,(a1-m),(a2+a1-2m),(a3+a2+a1-3m)……
            for(int i = 1 ;i<n; ++i)
                c[i] = c[i-1] + a[i] - t;
            sort(c,c+n);
            //pos为中位数
            ll pos = c[n/2],ans = 0;
            for(int i = 0; i<n;++i) ans+=fabs(pos-c[i]);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    jquery中 append 和appendto的区别
    vb的property 和event
    VB 基础语法以及教学视频
    outlook 2007 IMAP设置和配置
    浏览器文档播放Shockwave Flash 插件问题
    VB execl文件后台代码,基础语法
    VB中后台打开Excel文件实现代码
    excel文件后台代码
    DataTable中执行DataTable.Select("条件"),
    多个不同的表合并到一个datatable中,repeater在绑定datatable
  • 原文地址:https://www.cnblogs.com/pengwill/p/7367133.html
Copyright © 2011-2022 走看看