UVA - 11300 espalhando a riqueza (fórmula derivação)

Descrição

regime comunista está tentando redistribuir a riqueza em uma aldeia. Eles decidiram sentar-se todos
em torno de uma mesa circular. Em primeiro lugar, todo mundo tem convertido todas as suas propriedades para moedas de igual valor,
de modo que o número total de moedas é divisível pelo número de pessoas na aldeia. Finalmente, cada
pessoa dá um número de moedas para a pessoa à sua direita e um número de moedas para a pessoa à sua esquerda,
de tal forma que, no final, todo mundo tem o mesmo número de moedas. Dado o número de moedas de cada pessoa,
calcular o número mínimo de moedas que devem ser transferidas usando este método de modo que todos
tem o mesmo número de moedas.

Entrada

Há um número de entradas. Cada entrada começa com n (n <1000001), o número de pessoas na
aldeia. n linhas seguem, dando o número de moedas de cada pessoa na aldeia, no sentido anti-horário
fim ao redor da mesa. O número total de moedas vai caber dentro de um número inteiro de 64 bits sem sinal.

Saída

Para cada entrada, saída o número mínimo de moedas que devem ser transferidos em uma única linha.

Entrada simples

3
100
100
100
4
1
2
5
4

saída simples

0
4

Análise das idéias:

  Uma vez que o número total de moedas do que o número total de pessoas em um inteiro, usamos m para representar o número, ou seja, depois de múltiplos pontos de terminar moedas, todo mundo tem m moedas mãos, usamos um array para representar um

每个人在分硬币之前的每个人的硬币数,用x数组来表示第i个人给他前一个人的硬币数,那么就有A[i]-x[i]+x[i+1]=m,即x[i+1]=x[i]-A[i]+m;

将xi往后推则有:

x2=x1-A[i]+m;
x3=x2-A2+m=x1-A[1]-A[2]+2*m;
x4=x3-A3+m=x1-A[1]-A[2]-A[3]+3*m;
于是我们为了简化这些式子,用C[1]=A[1]-m,C[2]=c[1]+A[2]-m ··· ···
则有

x2=x1-C[1];
x3=x1-C[2];
x4=x1-C[3];
···
我们最终要求的就是|x1|+|x1-C1|+|x1-C2|+···+|x1-Cn-1|最小,则我们取得x1应该为ci的中位数,最终统计答案即可。

开long long

附上代码:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1e6+10;
 6 long long a[N],c[N],m,n,sum;
 7 int main(){
 8     while(scanf("%lld",&n)==1){
 9         memset(a,0,sizeof(a));
10         memset(c,0,sizeof(c));
11         sum=0;       //用于计算sum 
12         for(int i=1;i<=n;++i){
13             scanf("%lld",&a[i]);
14             sum+=a[i];
15         }
16         m=sum/n;
17         for(int i=1;i<=n;++i)
18             c[i]=c[i-1]+a[i]-m; //由前面的公式得到 
19         sort(c+1,c+n+1);
20         long long x1=c[n/2],ans=0; //x1取c[]的中位数 
21         for(int i=1;i<=n;++i)
22             ans+=abs(x1-c[i]);//统计答案. 
23         printf("%lld\n",ans);
24     }
25     return 0;
26 }

 

Acho que você gosta

Origin www.cnblogs.com/li-jia-hao/p/12663607.html
Recomendado
Clasificación