贪心&公式推导 思路

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DADDY_HONG/article/details/84928350

Money

Submit Page    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 11     Solved: 8    


Description

ZJ开公司,年年荣登315晚会。

315当天,一大帮员工来ZJ公司讨工资。(显然又欠工资了囧)。

员工们围成一个圈,把ZJ围在中间,打算用暴力手段讨取工资。

机智如ZJ早就料到这种情况了,所以ZJ身上带了钱。为了拖延时间,ZJ故意把钱不平衡地分给每个员工,这样,员工们就会因为分钱的事耽误时间。而ZJ就可以乘机逃跑了。。。

员工们的钱不平衡了,他们很不高兴。所以他们要开始交换钱。I的钱只能给I+1或者I-1。(1号的可以给n号,n号也可以给1号)。传递一块钱的时间是1s。

QQtan作为员工首领见状,立刻想出了办法,使传递的钱的数量最少(每秒钟只允许一个人传递1块钱,ZJ给钱的时间不算在内)。

你作为ZJ公司的首席程序猿,需要告诉ZJ,他有多少时间用来逃跑。

Input

第一行n,员工数量 第2行到n+1行,整数a[i] 每个员工已经拿到的钱。 N<=1000000

Output

一个整数,ZJ还有多久可以逃跑。

Sample Input

4
1
2
5
4

Sample Output

4

详见白书题目。

设 i 初始金钱为 ai,可算出每人应得的平均钱数M。

设 xi 为 i 给 i-1 的金币数,那么就可以列出n-1个有效方程(第n个可以由前n-1个推导出来):

ai + x(i+1) - xi = M;( 1 <= i <n )

x2 = x1 - a1 + M = x1 - C1(C1=a1-M,Ci = (a1+……+ai)- i*M);

……

xi+1 = xi - Ci;( 1 <= i < n )

所求应为|x1|+……+|xi|+……+|xn| = |x1| + |x1-C1| +……+ |x1-C(i-1)| +…… + |x1-C(n-1)|,可看作n个点到x1的距离和,x1应为其中某点,使其最小即找0,C1……C(n-1)的中位数。

很玄妙。

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int maxn=1e6+10;

int n;
long long m=0;
long long a[maxn],c[maxn];
long long ans=0;

int main()
{
     scanf("%d",&n);
     for(int i=0;i<n;++i){
          scanf("%lld",&a[i]);
          m+=a[i];
     }
     m/=n;
     c[0]=0;
     for(int i=1;i<n;++i){
          c[i]=c[i-1]+a[i]-m;
     }
     sort(c,c+n);
     long long x=c[n/2];
     for(int i=0;i<n;++i){
          ans+=llabs(x-c[i]);
     }
     printf("%lld\n",ans);

     return 0;
}

猜你喜欢

转载自blog.csdn.net/DADDY_HONG/article/details/84928350
今日推荐