uva11300Spreading the Wealth<数学>

链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2275

思路

原来金币数为a1,a2,`````an;

最终的金币为这些数的平均值,设为M

xi表示i给i+1的金币个数

a1+xn-x1=M
a2+x1-x2=M
a3+x2-x3=M
a4+x3-x4=M
.......
an+x(n-1)-xn=M
利用后面n-1个等式,用x1表示 x2,x3,...xn
x2=x1-(M-a2)
x3=x1-(2*M-a2-a3);
....

结果就是求|x1|+|x1-b1|+|x1-b2|+...+|x1-b[n-1]|的最小值,取中位数;

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 typedef long long LL;
 9 int N;
10 LL c[1000005], sum, M, a;
11 LL Labs(  LL a )
12 {
13     return a>0?a:-a;
14 }
15 int main( )
16 {
17     while( scanf("%d", &N )!= EOF ){
18         sum=0, c[0]=0;
19         for( int i=1; i<=N; ++ i ){
20             scanf( "%lld", &a );
21             sum+=a;    
22             c[i]=sum;
23         }
24         M=sum/N;
25         sum=0;
26         for( int i=1; i<=N; ++ i ){
27             c[i]-=i*M;
28         }
29         sort( c, c+N );
30         M=c[N/2];
31         for( int i=0; i<N; ++ i ){
32             c[i]-=M;
33             sum+=Labs(c[i]);
34         }
35         printf( "%lld\n", sum );
36     }
37     return 0;
38 }
原文地址:https://www.cnblogs.com/jian1573/p/2857081.html