UVa 11300 Spreading the wealth
2017-08-30 15:24
281 查看
题解:
显然我们这里可以设一些方程,因为我们最后要让每一个人的金币数相等,那么我们现在可以假设每个人向左边的人给了多少金币,比如我们令x2为2号给1号了多少金币,当然,如果给的金币的数量是负的,那么实际上是1给2了金币。那么我们显然可以得到如下方程
令M=sum/n,即最后的每个人的值
A1−x1+x2=M
A2−x2+x3=M
A3−x3+x4=M
......
An−1−xn−1+xn=M
显然我们可以通过这些方程来进行求解,具体的方式是,我们把所有的x2,x3,x4等全部转化为x1。
A1−x1+x2=M−>x2=M−A1+x1=x1−C1
这里我们让C1表示A1−M
显然C数组我们可以处理出来,那么现在我们要最小化的显然是abs(x1)+abs(x2)+...+abs(xn)
所以把所有的xtmp转化为x1−Ctmp−1的形式,然后再进行最小化。
显然最后变成了abs(x1)+abs(x1−C1)+...abs(x1−Cn−1)的最小值,显然我们只需要对C数组进行排序,然后选取其中点作为x1那么接下来的事情就是O(n)统计了。
代码:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; long long a[1000000+10],sum,M,c[1000000+10]; int n; int main(){ while(scanf("%d",&n)!=EOF&&n){sum=0; for(register int i=1;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i]; M=sum/n;c[0]=0; for(register int i=1;i<=n-1;i++)c[i]=c[i-1]+a[i]-M; sort(c+0,c+n);long long num=c[n/2]; long long ans=0;for(register int i=0;i<=n-1;i++)ans+=abs(num-c[i]); printf("%lld\n",ans); } return 0; }
相关文章推荐
- UVA 11300 Spreading the Wealth
- UVA 11300 Spreading the Wealth
- UVA - 11300 Spreading the Wealth (公式)
- UVA 题目11300 - Spreading the Wealth
- UVa - 11300 - Spreading the Wealth ( 数学推导 )
- UVa-11300 - Spreading the Wealth(中位数)
- uva 11300 Spreading the Wealth
- Uva 11300 Spreading the Wealth (代数分析 + 中位数)
- UVa - 11300 Spreading the Wealth (代数分析)
- UVa 11300 Spreading the Wealth
- [训练指南] 第一章 例题3 分金币 (Spreading the wealth,Uva 11300)
- UVa 11300 Spreading The Wealth
- UVA 11300-Spreading the Wealth
- Uva 11300 Spreading the Wealth
- uva 11300 - Spreading the Wealth
- uva 11300 Spreading the Wealth
- UVa 11300 Spreading the Wealth——中位数
- UVa 11300 - Spreading the Wealth
- UVA - 11300 Spreading the Wealth 公式+中位数
- UVA - 11300 Spreading the Wealth